2011-08-01 16 views
16

W mojej witrynie użytkownicy mogą wklejać tekst (w tym przypadku adres URL) do pola wejściowego. Chciałbym uchwycić wartość tekstu, który został wklejony za pomocą jQuery. Mam to do pracy w FF za pomocą kodu poniżej, ale nie działa w IE (nie sądzę IE obsługuje "wklej" zdarzenia).Jak przechwycić wartość wejściową w przypadku wklejania?

Ktoś wie, jak to zrobić we wszystkich nowoczesnych przeglądarkach? Znalazłem kilka innych odpowiedzi na to na SO, ale większość z nich to tylko FF i żaden nie oferował kompletnego rozwiązania.

Oto kod mam tak daleko:

$("input.url").live('paste', function(event) { 
    var _this = this; 
    // Short pause to wait for paste to complete 
    setTimeout(function() { 
     var text = $(_this).val(); 
     $(".display").html(text); 
    }, 100); 
}); 

JSFiddle: http://jsfiddle.net/TZWsB/1/

+2

http://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste-event-cross-browser/2177059#2177059 - podobne – Avien

+0

dzięki @Avien, wow, że pewne skomplikowany hack :) niestety czytając rozwiązania żaden z nich nie działa poprawnie w 100% lub działa we wszystkich nowoczesnych przeglądarkach. –

+0

Ten też może pomóc, używa jquery i jest o wiele prostszy: http://stackoverflow.com/questions/2903991/how-to-detect-ctrlv-ctrlc-using-javascript – sitnik

Odpowiedz

21

jQuery ma problem z żywą metodą ze zdarzeniem wklejania w IE; Obejście:

$(document).ready(function() { 
    $(".url").bind('paste', function(event) { 
     var _this = this; 
     // Short pause to wait for paste to complete 
     setTimeout(function() { 
      var text = $(_this).val(); 
      $(".display").html(text); 
     }, 100); 
    }); 
}); 

Fiddle: http://jsfiddle.net/Trg9F/

+0

+1 dzięki @scessor, to jest bardzo pomocne wiedzieć. Problem polega na tym, że pozwalam użytkownikom dynamicznie dodawać więcej danych wejściowych, więc potrzebuję metody na żywo. czy istnieje sposób na to, aby ta praca działała na żywo inaczej niż zhakowanie rozwiązania obejmującego ukryte dane wejściowe? –

+0

Mam rozwiązanie bez live: gdy dodasz dane wejściowe dynamicznie, możesz odłączyć wszystkie węzły za pomocą adresu URL klasy i ponownie powiązać to zdarzenie paste; niezbyt ładne, ale proste. – scessor

+1

który działa! dzięki! –

1

Może spróbuj użyć zdarzenia onblur zamiast. Tak więc użytkownik c/p do danych wejściowych i po opuszczeniu pola skrypt sprawdza, co tam jest. To może zaoszczędzić wiele kłopotów, ponieważ działa na mysz i klawisz c/p, a także ręcznie wprowadzane dane wejściowe.

+0

thanks @ qw3n. Problem polega na tym, że na stronie znajduje się tylko pole URL, więc na pewno pojawią się przypadki, gdy użytkownik wklei się w adresie URL i trafi go (bez opuszczania pola). –

+0

@rolling stone Ok dobrze, możesz zrobić dwufazowy czek. Pobierz zdarzenie 'onsubmit' i sprawdź dane wejściowe.Jeśli pusty return true else return false. Problem polega na tym, że musisz coś zrobić, aby funkcja nie działała dwa razy. Ponieważ zdarzenie 'onblur' nadal będzie uruchamiane. Może mieć zmienną binarną do przełączania, gdy wystrzeliłeś zdarzenie z jednej funkcji. Mam nadzieję, że to ma sens. Jest to skomplikowane, ale myślę, że mniej, niż alternatywa. – qw3n

16

wykrywać zdarzenie change jak paste. change będzie rzucał niezawodnie na zmienione pole przed wysłaniem, natomiast paste dzieje się tylko w przeglądarkach, które obsługują go na jawnym wklejeniu; nie będą one uruchamiane przez inne czynności edycyjne, takie jak przeciąganie i upuszczanie, wycinanie-kopiowanie, cofanie ponownej edycji, sprawdzanie pisowni, zastępowanie IME itd.

Problem z change polega na tym, że nie strzela od razu, tylko po zakończeniu edycji w polu. Jeśli chcesz przechwycić wszystkie zmiany w momencie ich wystąpienia, wydarzenie będzie miało postać input ... z tą różnicą, że jest to nowa funkcja HTML5, która nie jest obsługiwana wszędzie (w szczególności: IE < 9). Można to zrobić przez prawie wszystkie połowu tych zdarzeń:

$('.url').bind('input change paste keyup mouseup',function(e){ 
    ... 
}); 

Ale jeśli chcesz zdecydowanie połowu każda zmiana szybko w przeglądarkach, które nie obsługują input, nie masz wyboru, ale do sondowania wartość na setInterval.

+0

+1 dzięki @bobince! Powinienem chyba wspomnieć, że wszyscy użytkownicy będą robić (cóż, powinienem powiedzieć, że powinienem robić) w tym polu wejściowym wkleja się w adresie URL. również wygląda na to, że się mylę, a IE obsługuje "wklejanie", ma tylko pewne problemy z "live" i "paste". moim problemem jest dynamiczne generowanie pewnych treści w oparciu o adres URL, który wklejałem do użytkownika, aby upewnić się, że jest poprawny przed przesłaniem. faktycznie wyłączam przycisk wysyłania, gdy adres URL jest wklejany, aż do funkcji jQuery, która wykonuje wszystko, co jest kompletne. Każda rada byłaby doceniona! –

+0

Tak, 'onpaste' nie bańka w niektórych sytuacjach w IE, a jQuery' live' używa delegacji zdarzeń, która wymaga propagacji. Istnieją również inne problemy związane z przeglądarką, takie jak nierozpuszczanie wiadomości tekstowych w przeglądarce Safari. Niezależnie od problemów ze zgodnością, radzę pozwolić, aby pole zostało wypełnione w dowolny sposób, jaki wybierze użytkownik, w tym bezpośrednie pisanie i przeciąganie i upuszczanie, a nie kierowanie tylko na operacje wklejania. – bobince

+0

dzięki @bobince, na pewno wpłynie to na to, czy "zmienisz" najlepsze wydarzenie do przechwycenia drag-and-drop? –

3

Jeszcze lepiej jest używać e.originalEvent.clipboardData.getData ("tekst"); aby pobrać wklejone dane;

$("input").on("paste", function(e) { 
    var pastedData = e.originalEvent.clipboardData.getData('text'); 
    // ... now do with pastedData whatever you like ... 
}); 

W ten sposób można uniknąć przekroczenia limitu czasu i jest on obsługiwany we wszystkich głównych przeglądarkach.

+0

Podoba mi się ten pomysł, ale dla mnie e.originalEvent ma wiele atrybutów, ale nie ma pola/atrybutu clipboardData :([FYI Używam Microsoft TypeSafe i JQuery 3.1.1 i jQuery UI 1.12.1 do napisania mojego Javascript.] – Zeek

14
$('input').on('paste', function(e) { 
    // common browser -> e.originalEvent.clipboardData 
    // uncommon browser -> window.clipboardData 
    var clipboardData = e.clipboardData || e.originalEvent.clipboardData || window.clipboardData; 
    var pastedData = clipboardData.getData('text'); 
}); 
+0

Ze wszystkich szukanych przeze mnie rozwiązań, na razie tylko to dla mnie działa. – palerdot

+4

To powinna być poprawna odpowiedź. –

Powiązane problemy