Jak wykryć Ctrl + V, Ctrl + C za pomocą JavaScript?

173

Jak wykryć ctrl+ v, ctrl+ cużywając Javascript?

Muszę ograniczyć wklejanie w moich obszarach tekstowych, użytkownik końcowy nie powinien kopiować i wklejać treści, użytkownik powinien tylko wpisywać tekst w obszarze tekstowym.

Jak to osiągnąć?

Ramakrishnan
źródło
3
Jaki jest tego cel? Jedyne dwa uzasadnione scenariusze, które przychodzą mi do głowy, to pola haseł (których i tak nie można skopiować) i test szybkości pisania. Jestem pewien, że możesz wykryć podejrzanie szybkie pisanie.
Paul Butcher
9
@Paul Butcher, @Propeng: Są scenariusze, w których tego potrzebujesz. Bardzo prosty przykład: strona do nauki języków obcych. Efekt uczenia się jest wzmocniony, jeśli wpiszesz słowa odręcznie zamiast używać kopiowania i wklejania.
back2dos
2
Inną uzasadnioną sytuacją może być podwójny wpis, aby wykryć błędy (np. Wpisz swój e-mail dwukrotnie, abyśmy wiedzieli, że nie ma w nim literówki). Mimo to taki użytkownik mógłby zachować listę losowo generowanych adresów e-mail (np. Wiadomości e-mail) i prawdopodobnie chciałby ją wkleić dla dokładności.
Paul Butcher
40
@Paul Butcher - to wcale nie jest uzasadniona sytuacja, nienawidzę witryn, które to robią i zawsze kopiuję / wklejam mój (długi) adres e-mail z jednego pola do drugiego. Przerwanie kopiowania / wklejania jest głównym problemem z użytecznością. To naprawdę wyrzuca użytkownika, ponieważ jest tak fundamentalny dla ich modelu mentalnego, że oczekują, że „po prostu zadziała”. To tak, jakbyś próbował pociągnąć za drzwi, które odsunęły się od ciebie zamiast do ciebie!
EMP
4
Ilekroć taka kopia wklej nie jest dozwolona na stronie, co robię, to wklejam tekst w inne miejsce (używam paska adresu URL), a następnie Ctrl + A (zaznacz tekst właśnie wklejony w adresie URL), przeciągnij i upuść pole w przeglądarce, gdzie wklejanie jest wyłączone. Myślę, że na dzień dzisiejszy nie można temu zapobiec.
Janakiram

Odpowiedzi:

180

Zrobiłem to z zainteresowania. Zgadzam się, że to nie jest właściwe postępowanie, ale myślę, że powinna to być decyzja operatora ... Ponadto kod można łatwo rozszerzyć, aby dodać funkcjonalność, zamiast ją usuwać (jak bardziej zaawansowany schowek lub Ctrl+ swyzwalanie serwera -side save).

$(document).ready(function() {
    var ctrlDown = false,
        ctrlKey = 17,
        cmdKey = 91,
        vKey = 86,
        cKey = 67;

    $(document).keydown(function(e) {
        if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = true;
    }).keyup(function(e) {
        if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = false;
    });

    $(".no-copy-paste").keydown(function(e) {
        if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)) return false;
    });
    
    // Document Ctrl + C/V 
    $(document).keydown(function(e) {
        if (ctrlDown && (e.keyCode == cKey)) console.log("Document catch Ctrl+C");
        if (ctrlDown && (e.keyCode == vKey)) console.log("Document catch Ctrl+V");
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Ctrl+c Ctrl+v disabled</h3>
<textarea class="no-copy-paste"></textarea>
<br><br>
<h3>Ctrl+c Ctrl+v allowed</h3>
<textarea></textarea>

Również dla wyjaśnienia, ten skrypt wymaga biblioteki jQuery.

Codepen demo

EDYCJA: usunięto 3 zbędne wiersze (w tym np. Które) dzięki sugestii Tima Downa (patrz komentarze)

EDYCJA: dodano obsługę komputerów Mac ( cmdklawisz zamiast ctrl)

jackocnr
źródło
4
Dlaczego obsługa keydowni jest keyupwłączona document? Możesz przetestować klawisz Ctrl w programie $(".no-copy-paste").keydownobsługi. Ponadto e.keyCode || e.whichbit nie jest potrzebny : e.keyCodedziała we wszystkich przeglądarkach, w których e.whichdziała, więc e.whichnigdy nie będzie używany. Być może zastanawiałeś się, jak uzyskać kod postaci z keypresswydarzenia? Wreszcie, nie zrobi to nic z pastami z menu kontekstowego lub edycji, ale przypuszczam, że OP nie pytał o to bezpośrednio.
Tim Down
@Tim: Funkcje obsługi klawisza Ctrl w dokumencie mają być ogólne - ponieważ mogą nie chcieć, aby zmienna ctrlDown była wyłącznie połączona z wejściami bez kopiowania i wklejania. To być może OTT. Dzięki za e.which wskazówkę - od tego czasu spędziłem pół godziny na badaniu różnych przypadków użycia e.keyCode i e., które z keydown () i keypress (), i co za bałagan (szczególnie w Firefoxie)!
jackocnr
1
jackocnr: Polecam artykuł Jana Woltera na temat obsługi kluczy JavaScript: unixpapa.com/js/key.html Użyłem go wiele razy w celach informacyjnych i nie znalazłem błędu.
Tim Down
3
Koleś! Dzięki! To jest dokładnie to, czego potrzebowałem, aby umożliwić użytkownikom wybranie „elementu” (pozycji kalendarza) w aplikacji internetowej, którą piszę, nacisnąć ctrl + c, aby go „skopiować”, a następnie ctrl + v, aby go „wkleić”, wszystko bez faktycznie wchodząc w interakcję z wszechmocnym błogosławionym schowkiem. ctrl + c Pamiętam, w co zostali kliknięci, ctrl + v Duplikuję to, każdy wygrywa.
Dan F
2
Nie jestem ekspertem ani nic takiego, ale myślę, że prawdopodobnie lepiej byłoby przetestować e.metaKeylub e.ctrlKeybyć, truezamiast przypisywać wartości liczbowe do klawiszy i testować je.
sluther
52

Za pomocą jquery możesz łatwo wykryć kopiowanie, wklejanie itp., Wiążąc funkcję:

$("#textA").bind('copy', function() {
    $('span').text('copy behaviour detected!')
}); 
$("#textA").bind('paste', function() {
    $('span').text('paste behaviour detected!')
}); 
$("#textA").bind('cut', function() {
    $('span').text('cut behaviour detected!')
});

Więcej informacji tutaj: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/

Chris Andersson
źródło
1
Niestety, ta metoda uruchomi się tylko w Firefoksie po zaznaczeniu tekstu
Yassir Ennazk
44

Chociaż może to być denerwujące, gdy jest używane jako środek antypiracki, widzę, że mogą istnieć przypadki, w których byłoby to uzasadnione, więc:

function disableCopyPaste(elm) {
    // Disable cut/copy/paste key events
    elm.onkeydown = interceptKeys

    // Disable right click events
    elm.oncontextmenu = function() {
        return false
    }
}

function interceptKeys(evt) {
    evt = evt||window.event // IE support
    var c = evt.keyCode
    var ctrlDown = evt.ctrlKey||evt.metaKey // Mac support

    // Check for Alt+Gr (http://en.wikipedia.org/wiki/AltGr_key)
    if (ctrlDown && evt.altKey) return true

    // Check for ctrl+c, v and x
    else if (ctrlDown && c==67) return false // c
    else if (ctrlDown && c==86) return false // v
    else if (ctrlDown && c==88) return false // x

    // Otherwise allow
    return true
}

Użyłem event.ctrlKeyzamiast sprawdzać kodu klucza, ponieważ w większości przeglądarek w systemie Mac OS X Ctrl/ Altzdarzenia „w dół” i „w górę” nigdy nie są wyzwalane, więc jedynym sposobem wykrycia jest użycie event.ctrlKeynp. Zdarzenia c po Ctrlkluczu przytrzymany. Ja również podstawione ctrlKeyz metaKeydla Mac.

Ograniczenia tej metody:

  • Opera nie pozwala na wyłączanie zdarzeń kliknięcia prawym przyciskiem myszy

  • O ile wiem, nie można zapobiec przeciąganiu i upuszczaniu między oknami przeglądarki.

  • edit-> copyelement menu na przykład Firefox może nadal pozwalają kopiowania / wklejania.

  • Nie ma również gwarancji, że dla osób z różnymi układami klawiatury / lokalizacjami, które kopiują / wklejają / wycinają, są tymi samymi kluczowymi kodami (chociaż układy często są zgodne z tym samym standardem co angielski), ale ogólne „wyłącz wszystkie klawisze sterowania” oznacza, że ​​wybierzesz wszystko itd. zostanie również wyłączony, więc myślę, że to kompromis, który należy osiągnąć.
krio
źródło
14

Jest jeszcze inny sposób w ten sposób: onpaste , oncopyi oncutzdarzenia mogą być rejestrowane i anulowane w IE, Firefox, Chrome, Safari (z pewnymi problemami drobnych), jedynym ważnym przeglądarka nie pozwala na anulowanie tych zdarzeń jest Opera.

Jak widać w mojej drugiej odpowiedzi przechwytywanie Ctrl+ vi Ctrl+ cma wiele efektów ubocznych i nadal nie uniemożliwia użytkownikom wklejania za pomocą Editmenu Firefoksa itp.

function disable_cutcopypaste(e) {
    var fn = function(evt) {
        // IE-specific lines
        evt = evt||window.event
        evt.returnValue = false

        // Other browser support
        if (evt.preventDefault) 
            evt.preventDefault()
        return false
    }
    e.onbeforepaste = e.onbeforecopy = e.onbeforecut = fn
    e.onpaste = e.oncopy = e.oncut = fn
}

Safari nadal ma drobne problemy z tą metodą (czyści schowek zamiast wycinania / kopiowania, zapobiegając domyślnemu), ale wydaje się, że ten błąd został już naprawiony w Chrome.

Więcej informacji można znaleźć pod adresem : http://www.quirksmode.org/dom/events/cutcopypaste.html i na powiązanej stronie testowej http://www.quirksmode.org/dom/events/tests/cutcopypaste.html .

krio
źródło
9

Demo na żywo: http://jsfiddle.net/abdennour/ba54W/

$(document).ready(function() {

    $("#textA").bind({
        copy : function(){
            $('span').text('copy behaviour detected!');
        },
        paste : function(){
            $('span').text('paste behaviour detected!');
        },
        cut : function(){
            $('span').text('cut behaviour detected!');
        }
    });

}); 
Abdennour TOUMI
źródło
8

Krótkie rozwiązanie uniemożliwiające użytkownikowi korzystanie z menu kontekstowego, kopiowania i wycinania w jQuery:

jQuery(document).bind("cut copy contextmenu",function(e){
    e.preventDefault();
});

Przydatne może być również wyłączenie zaznaczania tekstu w CSS:

.noselect {  
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
     user-select: none;
}
jendarybak
źródło
4

Jeśli używasz tej ctrlKeywłaściwości, nie musisz utrzymywać stanu.

   $(document).keydown(function(event) {
      // Ctrl+C or Cmd+C pressed?
      if ((event.ctrlKey || event.metaKey) && event.keyCode == 67) {
         // Do stuff.
      }

      // Ctrl+V or Cmd+V pressed?
      if ((event.ctrlKey || event.metaKey) && event.keyCode == 86) {
         // Do stuff.
      }

      // Ctrl+X or Cmd+X pressed?
      if ((event.ctrlKey || event.metaKey) && event.keyCode == 88) {
         // Do stuff.
      } 
    }
Crashalot
źródło
TO jest poprawna odpowiedź! Zdarzenie ma właściwość ctrlKey = true, jeśli naciśnięto klawisz. Nie potrzebujemy żadnych dodatkowych wydarzeń.
JanBrus
3

Napisałem wtyczkę jQuery, która przechwytuje naciśnięcia klawiszy. Można go używać do włączania wprowadzania skryptów w wielu językach w formularzach HTML bez systemu operacyjnego (z wyjątkiem czcionek). To około 300 linii kodu, może chcesz rzucić okiem:

Generalnie uważaj na tego typu przeróbki. Napisałem wtyczkę dla klienta, ponieważ inne rozwiązania nie były dostępne.

miku
źródło
3

Możesz użyć tego kodu do prawego kliknięcia, CTRL+ C, CTRL+ V, CTRL+ Xwykryć i zapobiec ich działaniu

$(document).bind('copy', function(e) {
        alert('Copy is not allowed !!!');
        e.preventDefault();
    }); 
    $(document).bind('paste', function() {
        alert('Paste is not allowed !!!');
        e.preventDefault();
    }); 
    $(document).bind('cut', function() {
        alert('Cut  is not allowed !!!');
        e.preventDefault();
    });
    $(document).bind('contextmenu', function(e) {
        alert('Right Click  is not allowed !!!');
        e.preventDefault();
    });
Varun Naharia
źródło
3

zamiast onkeypress, użyj onkeydown.

<input type="text" onkeydown="if(event.ctrlKey && event.keyCode==86){return false;}" name="txt">
atiruz
źródło
2

Innym podejściem (bez wtyczki) jest po prostu użycie ctrlKeywłaściwości obiektu zdarzenia, który jest przekazywany. Wskazuje, czy Ctrlzostał naciśnięty w momencie zdarzenia, na przykład:

$(document).keypress("c",function(e) {
  if(e.ctrlKey)
    alert("Ctrl+C was pressed!!");
});

Zobacz także jquery: keypress, ctrl + c (lub podobne combo) .

Abu Ghufran
źródło
0

Nie zapominaj, że chociaż możesz być w stanie wykryć i zablokować Ctrl+ C/ V, nadal możesz zmienić wartość określonego pola.
Najlepszym tego przykładem jest funkcja Inspect Element w przeglądarce Chrome, która pozwala zmienić właściwość wartość pola.

BlueCacti
źródło
0

mam już twój problem i rozwiązałem go za pomocą następującego kodu .. które akceptują tylko liczby

$('#<%= mobileTextBox.ClientID %>').keydown(function(e) {
            ///// e.which Values
            // 8  : BackSpace , 46 : Delete , 37 : Left , 39 : Rigth , 144: Num Lock 
            if (e.which != 8 && e.which != 46 && e.which != 37 && e.which != 39 && e.which != 144
                && (e.which < 96 || e.which > 105 )) {
                return false;
            }
        });

możesz wykryć Ctrlide.which == 17

Amr Badawy
źródło
-1

Możesz słuchać zdarzenia naciśnięcia klawisza i zatrzymać domyślne zdarzenie (wprowadzanie tekstu), jeśli pasuje do określonych kodów klawiszy

baloo
źródło
-1

Ważna uwaga

Używałem e.keyCodeprzez jakiś czas i wykryłem, że kiedy naciskam ctrl+ ., ten atrybut zwraca nieprawidłową liczbę, 190, podczas gdy kod ascii. to 46!

Więc powinieneś użyć e.key.toUpperCase().charCodeAt(0)zamiast e.keyCode.

Amir Fo
źródło
-4

Istnieje kilka sposobów, aby temu zapobiec.

Jednak użytkownik zawsze będzie mógł wyłączyć javascript lub po prostu spojrzeć na kod źródłowy strony.

Kilka przykładów (wymaga jQuery)

/**
* Stop every keystroke with ctrl key pressed
*/
$(".textbox").keydown(function(){
    if (event.ctrlKey==true) {
        return false;
    }
});

/**
* Clear all data of clipboard on focus
*/
$(".textbox").focus(function(){
    if ( window.clipboardData ) {
        window.clipboardData.setData('text','');
    }
});

/**
* Block the paste event
*/
$(".textbox").bind('paste',function(e){return false;});

Edycja: jak powiedział Tim Down, wszystkie te funkcje zależą od przeglądarki.

Gustavo Cardoso
źródło
2
Ma to wiele problemów: po pierwsze, nie będzie działać w przeglądarkach, które nie mają pastezdarzenia, które obejmuje wszystkie wersje Firefoksa starsze niż wersja 3. Po drugie, window.clipboardDatadotyczy tylko IE i uważam, że jest teraz domyślnie wyłączone w IE. . Po trzecie, wyłączanie wszystkich keydownzdarzeń, w których naciśnięty jest klawisz Ctrl, jest nadmierne: zapobiega się przydatnym skrótom klawiaturowym, takim jak Ctrl-A (zaznacz wszystko) i Ctrl-Z (cofnij). Po czwarte, jak wspominali inni, jest to naprawdę zła rzecz.
Tim Down
Masz rację, że nie działa w każdej przeglądarce. Nikt Blok ctrl jest rzeczywiście denerwujący. Przydało się to kiedyś, gdy klient chciał zablokować pole „Potwierdzający adres e-mail i hasło”.
Gustavo Cardoso,