Yakalama macunu girişi


210

Ben tarayıcıya yapıştırın girdi sanitize için bir yol arıyorum, bu jQuery ile yapmak mümkün mü?

Şimdiye kadar bunu yapmayı başardım:

$(this).live(pasteEventName, function(e) {
 // this is where i would like to sanitize my input
 return false;
}

Maalesef bu "küçük" sorun yüzünden gelişimim çığlık attı. Birisi beni doğru yöne yönlendirebilirse beni gerçekten mutlu bir kampçı yapardım.


6
Lütfen stackoverflow.com/a/1503425/749232 aynı sorunu yaşayan diğer kişilerin kullanımı için yanıt olarak işaretleyin . Bu benim için çözdü.
saji89

2
.live (), jquery 1.9'dan itibaren kullanımdan kaldırılmıştır, bunun yerine .on () yöntemini önerirler
Sameer Alibhai

Yanıtlar:


337

Tamam, aynı konuya çarptım .. Uzun yoldan gittim

$('input').on('paste', function () {
  var element = this;
  setTimeout(function () {
    var text = $(element).val();
    // do something with text
  }, 100);
});

.Val () işlevi doldurulana kadar küçük bir zaman aşımı süresi.

E.


20
Metin alanında zaten metin varsa ve yapıştırırsanız ve yapıştırılan metni istediyseniz ne olur?
barfoon

39
Mükemmel çalışıyor, teşekkürler. 0 zaman aşımı da işe yarar. Fonksiyonun sadece bir sonraki döngüye ertelenmesi gerekir.
Daniel Lewis

4
Benzer bir durumdaydım. Yapıştır olayı hemen gerçekleşmediği için zaman aşımı var, ancak pano içeriğinin yapıştırılması birkaç milisaniye sürüyor.
James

8
@ user563811: Resmi minimum zaman aşımının HTML5'te 4 ms olduğunu unutmayın.
pimvdb

4
Şerif'in dediği gibi, 0 ms olayı yığının altına koyuyor.
BobRodes

67

Aslında değeri doğrudan etkinlikten alabilirsiniz . Biraz geniş olsa nasıl olsun.

Eğer geçmesini istemiyorsanız false değerini döndürün.

$(this).on('paste', function(e) {

  var pasteData = e.originalEvent.clipboardData.getData('text')

});


1
ör. 11: window.clipboardData.getData ('text')
Wallstrider

4
Ancak, "originalEvent" özelliği gereksiniminin yalnızca olayı jQuery ile işliyorsanız gerektiğini unutmayın. Sadece e.clipboardData.getData('text')düz JavaScript ile yapabilirsiniz.
Asier Paz

En iyi cevap burada! Ancak - bağlamanın kısa el versiyonunun bununla çalışmadığı garip buldum, yani, bunu denersem hata: $ (this) .paste (function (e) {...}); hatta Bu kısa süreli
.on

niggle: kodda bir kapanış paren eksik. Görünüşe göre değişiklik, düzenleme olarak düzeltmeme izin vermeyecek kadar küçük.
Joachim Lous

42

Platformlar arası uyumluluk için, oninput ve onpropertychange olaylarını işlemelidir:

$ (something).bind ("input propertychange", function (e) {
    // check for paste as in example above and
    // do something
})

2
Hem yapıştır hem de keyup olayı yakalama işlevi gören güzel çözüm. Not: Bu olay işlevi giriş içeriğini vurgulamak eğer nedense iki kez ateşlenmesine neden olur ve daha sonra bir şeyler yazın en azından IE8 (birçok durumda önemli ama diğerleri muhtemelen çok önemli değil).
baacke

Güzel ! Ben bu konuda bilmiyordum, ve benim ihtiyaçlarına mükemmel uyum!
Marc Brillault

18

Aşağıdaki kodu kullanarak bir tür sabit:

$("#editor").live('input paste',function(e){
    if(e.target.id == 'editor') {
        $('<textarea></textarea>').attr('id', 'paste').appendTo('#editMode');
        $("#paste").focus();
        setTimeout($(this).paste, 250);
    }
});

Şimdi sadece caret konumu saklamak ve bu konuma eklemek gerekir o zaman ben hazırım ... Sanırım :)


1
Düzeltme konumu konumunu nasıl sakladınız?
Petah

@Petah Hangi öğenin odaklanacağını kontrol edebilir ve öğenin onun için düzeltme konumunu belirlediğini bilebilirsiniz .find(':focus'). Bkz bu .
Jacob

Unutmayın "canlı", "açık" lehine kullanımdan kaldırılmıştır
NBPalomino

inputfark yaratır :) Normalde bunları metin kutusu etkinliklerimde var keyup keydown paste inputama açıkçası nedenlerinize bağlı
Pierre

10

Hmm ... Sanırıme.clipboardData yapıştırılan verileri yakalamak için kullanabilirsiniz . Dışarı çıkmazsa, buraya bir göz atın .

$(this).live("paste", function(e) {
    alert(e.clipboardData); // [object Clipboard]
});

2
Bunu Safari'de çalıştırdığımda 'undefined'
alıyorum

1
clipboardData çoğu tarayıcıda korumalı (açık güvenlik deliği.)
podperson

2
Yalnızca Internet Explorer!
Lodewijk

9

Yapıştır olayını dinleyin ve bir keyup olay dinleyicisi ayarlayın. Keyup'da değeri yakalayın ve keyup olay dinleyicisini kaldırın.

$('.inputTextArea').bind('paste', function (e){
    $(e.target).keyup(getInput);
});
function getInput(e){
    var inputText = $(e.target).val();
    $(e.target).unbind('keyup');
}

6
Bu çok iyi, ancak sağ tıklama yapıştırma için çalışmıyor.
Joseph Ravenwolfe

Orta tıklatma yapıştırma (X11) için de çalışmaz, yalnızca yapıştırmak için klavyeyi kullandıklarında çalışır.
Jasen

7
$("#textboxid").on('input propertychange', function () {
    //perform operation
        });

İyi çalışacaktır.


6

Bu, istediklerinize yaklaşıyor.

function sanitize(s) {
  return s.replace(/\bfoo\b/g, "~"); 
};

$(function() {
 $(":text, textarea").bind("input paste", function(e) {
   try {
     clipboardData.setData("text",
       sanitize(clipboardData.getData("text"))
     );
   } catch (e) {
     $(this).val( sanitize( $(this).val() ) );
   }
 });
});

ClipboardData nesnesi bulunmadığında (IE dışındaki tarayıcılarda) şu anda öğenin tam değerini + clipboard'ed değerini aldığınızı lütfen unutmayın.

Bir girişten önce ve girişten sonra, yalnızca öğeye gerçekten hangi verilerin yapıştırıldığından sonraysanız, iki değeri ayırmak için bazı ekstra adımlar atabilirsiniz.


6
 $('').bind('input propertychange', function() {....});                      

Bu fare macunu olayı için çalışacaktır.


2
Bu en iyi kullanımdır.
Sinan Eldem

5

Alanın orijinal değerini ve alanın değişen değerini karşılaştırmaya ve farkı yapıştırılan değer olarak çıkarmaya ne dersiniz? Bu, alanda mevcut metin olsa bile yapıştırılan metni doğru bir şekilde yakalar.

http://jsfiddle.net/6b7sK/

function text_diff(first, second) {
    var start = 0;
    while (start < first.length && first[start] == second[start]) {
        ++start;
    }
    var end = 0;
    while (first.length - end > start && first[first.length - end - 1] == second[second.length - end - 1]) {
        ++end;
    }
    end = second.length - end;
    return second.substr(start, end - start);
}
$('textarea').bind('paste', function () {
    var self = $(this);
    var orig = self.val();
    setTimeout(function () {
        var pasted = text_diff(orig, $(self).val());
        console.log(pasted);
    });
});

5

Bu kod benim için sağ tıklamadan yapıştır veya doğrudan kopyala yapıştır için çalışıyor

   $('.textbox').on('paste input propertychange', function (e) {
        $(this).val( $(this).val().replace(/[^0-9.]/g, '') );
    })

Yapıştırdığımda metin kutusuna Section 1: Labour Costdönüşür 1.

Yalnızca float değerine izin vermek için bu kodu kullanıyorum

 //only decimal
    $('.textbox').keypress(function(e) {
        if(e.which == 46 && $(this).val().indexOf('.') != -1) {
            e.preventDefault();
        } 
       if (e.which == 8 || e.which == 46) {
            return true;
       } else if ( e.which < 48 || e.which > 57) {
            e.preventDefault();
      }
    });

4
document.addEventListener('paste', function(e){
    if(e.clipboardData.types.indexOf('text/html') > -1){
        processDataFromClipboard(e.clipboardData.getData('text/html'));
        e.preventDefault();

        ...
    }
});

Daha ileri:


text / html geçerli değil, yalnızca url ve metin.
Mike

@ Parçacığı doğrudan başvurulan belgelerden kopyaladım.
davidcondrey

Bunu yaklaşık bir gün denedim. text / html asla işe yaramaz. Ben 0 gecikme bir zaman aşımı ekleyerek sona erdi ve yapıştırma yaptıkları div html kapmak başardı. Birisi yardımcı olacak bir çalışma keman vardı. Belki de sadece yanlış yapıyorum ...
Mike

3

Bu örneğe bakın: http://www.p2e.dk/diverse/detectPaste.htm

Temel olarak oninput olayı ile her değişikliği izler ve sonra dize karşılaştırmasıyla yapıştırıp yapıştırmadığını kontrol eder. Oh, ve IE'de bir onpaste olayı var. Yani:

$ (something).bind ("input paste", function (e) {
    // check for paste as in example above and
    // do something
})

Yani olay meydana geldiğinde sadece yapıştırma metnini almak imkansız mı?
Christoffer Winterkvist

Sanırım, kendinizle başa çıkmak zorunda kalacaksınız, mesela, önce ve sonra karşılaştırın. Oldukça kolay olmalı. Ama neden sadece girdinin tamamını yeniden doğrulamıyorsunuz? Yavaş?
Ilya Birman

Bunu yapmanın mümkün olacağını düşündüm ama sanmıyorum, Şu anda bir textarea'ya yapıştırarak ve sonra son hedefine aktararak başka bir yöntem deniyorum. Bunun işe yarayacağını umuyorum.
Christoffer Winterkvist

İki dizenin başlangıcında (öncesi ve sonrası) maksimum eşleşen parçayı bulmanız yeterlidir. Oradan ve uzunluk farkına kadar her şey yapıştırılan metindir.
Ilya Birman

@IlyaBirman hayır değil: örn. Yapıştırılan metin orijinalin bir kısmını (veya tümünü) değiştiriyor olabilir
Jasen

1

Bu yöntem, jqueries content (). Unwrap () öğesini kullanır.

  1. İlk olarak, paste etkinliğini tespit edin
  2. Yapıştırdığımız öğede zaten bulunan etiketlere benzersiz bir sınıf ekleyin.
  3. Belirli bir zaman aşımından sonra, daha önce ayarladığınız sınıfa sahip olmayan tüm içeriği açıp çıkarma etiketlerini tarayın. Not: Bu yöntem, aşağıdaki örneğe bakın gibi kendiliğinden kapanan etiketleri kaldırmaz
    .

    //find all children .find('*') and add the class .within .addClass("within") to all tags
    $('#answer_text').find('*').each(function () {
    $(this).addClass("within");
    });
    setTimeout(function() {
    $('#answer_text').find('*').each(function () {
        //if the current child does not have the specified class unwrap its contents
        $(this).not(".within").contents().unwrap();
    });
    }, 0);

Kesinlikle şimdiye kadar görülen en iyi, en kısa ve kendi kendine konuşan cevap !!! Çok teşekkür ederim, benim günümü yaptın;)
webprogrammer

0

Bu oldukça aldatıcıydı. Yapıştırmanın işlevi, paste olay işlevi içindeki kodun yürütülmesinden önce güncellenmez. Yapıştır olay işlevi içinde diğer olayları çağırmayı denedim ama giriş değeri hala herhangi bir olay işlevi içinde yapıştırılan metin ile güncellenmez. Keyup dışındaki tüm olaylar bu. Yapıştır olayı içinden keyup çağırırsanız, yapıştırılan metni keyup olayı fonksiyonundan temizleyebilirsiniz. böyle ...

$(':input').live
(
    'input paste',
    function(e)
    {
        $(this).keyup();
    }
);

$(':input').live
(
    'keyup',
    function(e)
    {
        // sanitize pasted text here
    }
);

Burada bir uyarı var. Firefox'ta, giriş metnini her tuşta sıfırlarsanız, metin giriş genişliğinin izin verdiği görüntülenebilir alandan daha uzunsa, her tuşta değeri sıfırlamak, metni otomatik olarak metnin sonu. Bunun yerine metin, başlığın geriye doğru görünmesi için geriye doğru kayar.


onpaste, içerikler yapıştırılmadan önce çağrılır. Kendi macun fonksiyonunuzu oluşturmak, macunun sonuçlarını yıkamak için en az 4 ms'lik bir zaman gecikmesine ihtiyacınız vardır.
DragonLord

-1

Portlet-form-input-field sınıfıyla tüm alanlardan özel karakterleri kaldıracak komut dosyası:

// Remove special chars from input field on paste
jQuery('.portlet-form-input-field').bind('paste', function(e) {
    var textInput = jQuery(this);
    setTimeout(function() {
        textInput.val(replaceSingleEndOfLineCharactersInString(textInput.val()));
    }, 200);
});

function replaceSingleEndOfLineCharactersInString(value) {
    <%
        // deal with end-of-line characters (\n or \r\n) that will affect string length calculation,
        // also remove all non-printable control characters that can cause XML validation errors
    %>
    if (value != "") {
        value = value.replace(/(\x00|\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F)/gm,'');
        return value = value.replace(/(\r\n|\n|\r)/gm,'##').replace(/(\#\#)/gm,"\r\n");
    }
}

2
İlgili sterilizasyonun açıklamasını ve poster sorununu neden çözmenize yardımcı olabileceğini lütfen ekler misiniz? Bir kod bloğunun sağlanması, OP'nin (veya gelecekteki araştırmacıların) sorunun nasıl çözüleceğini anlamasına gerçekten yardımcı olmaz - sadece yanlış anlaşılmış kodu kopyalamayı / yapıştırmayı teşvik eder.
Troy Alford

-2

Burada bir uyarı var. Firefox'ta, giriş metnini her tuşta sıfırlarsanız, metin giriş genişliğinin izin verdiği görüntülenebilir alandan daha uzunsa, her tuşta değeri sıfırlamak, metni otomatik olarak metnin sonu. Bunun yerine metin, başlığın geriye doğru görünmesi için geriye doğru kayar.

function scroll(elementToBeScrolled) 
{
     //this will reset the scroll to the bottom of the viewable area. 
     elementToBeScrolled.topscroll = elementToBeScrolled.scrollheight;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.