Як виявити Ctrl + V, Ctrl + C за допомогою JavaScript?


173

Як виявити ctrl+ v, ctrl+ cза допомогою Javascript?

Мені потрібно обмежити вставки в своїх текстових областях, кінцевий користувач не повинен копіювати та вставляти вміст, користувач повинен лише вводити текст у текстовій області.

Як цього досягти?


3
Яка мета цього? Єдині два законних сценарію, про які я можу придумати, - це поля паролів (які ви все одно не можете скопіювати) та тест швидкості набору тексту. Я впевнений, що ви можете виявити підозріло швидко набравши текст.
Пол М'ясник

9
@Paul Butcher, @Propeng: Тут є сценарії, де це потрібно. Дуже простий приклад: Сайт для вивчення іноземних мов. Ефект навчання посилюється, якщо ви вводите слова вручну замість того, щоб скопіювати та вставити.
back2dos

2
Іншою правомірною ситуацією може бути те, що для виявлення помилок потрібен подвійний запис (наприклад, введіть електронну пошту двічі, щоб ми знали, що в ній немає помилки). Проте такий користувач може зберігати список випадково генерованих електронних адрес (наприклад, електронна пошта) і, ймовірно, захоче вставити його для точності.
Пол М'ясник

40
@Paul Butcher - це зовсім не правова ситуація, я ненавиджу сайти, які це роблять, і я завжди копіюю / вставляю свою (довгу) адресу електронної пошти з одного вводу на інший. Порушення копіювання / вставки є головною проблемою використання. Це дійсно відкидає користувача, оскільки це настільки принципово для їх ментальної моделі, що вони очікують, що він "просто працює". Це як би ви намагалися витягнути двері, і вона відкинулася від вас, а не до вас!
EMP

4
Щоразу, коли така копія вставити її не дозволено на сторінку, що я роблю, вставте текст десь в іншому місці (я використовую рядок URL), а потім Ctrl + A (виберіть текст, щойно вставлений в URL), перетягніть і впустіть у вікні перегляду, де вимкнено пасту. Я здогадуюсь, це сьогодні не можна запобігти.
Джанакірам

Відповіді:


180

Я просто робив це з інтересу. Я погоджуюсь, що це не правильно робити, але я думаю, що це повинно бути рішенням оп ... Також код можна легко розширити, щоб додати функціональність, а не забрати його (як більш досконалий буфер обміну або Ctrl+ sзапуск сервера -зберегти).

$(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>

Також для уточнення цього сценарію потрібна бібліотека jQuery.

Codepen demo

EDIT: видалено 3 надлишкових рядки (із залученням напр.) Завдяки пропозиції Тіма Дауна (див. Коментарі)

EDIT: додана підтримка Macs ( cmdключ замість ctrl)


4
Чому keydownі keyupобробники document? Ви можете перевірити наявність клавіші Ctrl у $(".no-copy-paste").keydownобробнику. Крім того, e.keyCode || e.whichбіт не потребує : e.keyCodeпрацює у всіх браузерах, в яких e.whichпрацює, тому e.whichніколи не буде використовуватися. Можливо, ви думали, як отримати код символу від keypressподії? Нарешті, це нічого не стосується вставок із контексту чи редагування меню, але я вважаю, що ОП не питала про це безпосередньо.
Тім Даун

@Tim: Обробники ключів Ctrl у документі мають бути загальними - оскільки вони можуть не бажати, щоб змінна ctrlDown була пов'язана виключно з введеннями без копіювання та вставки. Це, мабуть, ОТГ. Дякуємо за підказку egwich - я з тих пір витратив півгодини на дослідження різних випадків використання e.keyCode та e.which з keydown () та keypress (), і який хаос (особливо у firefox)!
jackocnr

1
jackocnr: Я рекомендую статтю про обробку ключа JavaScript Jan Wolter: unixpapa.com/js/key.html Я багато разів використовував її для довідки і не знайшов помилки.
Тім Даун

3
Чувак! Дякую! Це саме те, що мені потрібно було, щоб користувачі могли вибрати "елемент" (запис календаря) у веб-додатку, про який я пишу, натисніть ctrl + c, щоб "скопіювати" його, а потім ctrl + v, щоб "вставити" його, все без фактично взаємодіючи з всемогутним благословенним буфером обміну. ctrl + c Я пам’ятаю, на що натискають, ctrl + v Я копіюю його, усі виграють.
Дан Ф

2
Я не фахівець чи що-небудь, але я думаю, що, мабуть, було б краще протестувати e.metaKeyчи e.ctrlKeyбути trueзамість того, щоб призначати числові значення ключам та перевіряти їх.
повія

52

За допомогою jquery ви можете легко виявити копію, вставити тощо, зв’язавши функцію:

$("#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!')
});

Більше інформації тут: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/


1
На жаль, цей метод запустить Firefox лише у випадку вибору тексту
Yassir Ennazk

44

Хоча це може дратувати, коли його застосовують як антипіратський захід, я можу побачити, що можуть бути деякі випадки, коли це було б законно, так:

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
}

Я використовував, event.ctrlKeyа не перевіряв код ключа, як у більшості браузерів на Mac OS X Ctrl/ Alt"події вниз" і "вгору" ніколи не спрацьовують, тому єдиний спосіб виявити - це використовувати event.ctrlKeyв події c, наприклад, після Ctrlключа притиснуто. Я також заміщений ctrlKeyз metaKeyдля Маков.

Обмеження цього методу:

  • Opera не дозволяє відключати події правої кнопки миші

  • Перетягування між вікнами браузера, наскільки мені відомо, не можна запобігти.

  • edit-> copyпункт меню, наприклад , в Firefox все ще може дозволити копіювати / вставити.

  • Також немає гарантії, що для людей з різними розкладками / локалями клавіатури, які копіюють / вставляють / вирізають, є однакові ключові коди (хоча макети часто просто відповідають тому ж стандарту, що й англійська мова), але ковдра "відключити всі клавіші управління" означає, що виберіть усі тощо також буде відключено, тому я думаю, що це компроміс, який потрібно зробити.

14

Там ще один спосіб зробити це: onpaste , oncopyі oncutподії можуть бути зареєстровані і скасовані в IE, Firefox, Chrome, Safari (з деякими проблемами неповнолітніх), єдиний великий браузер , який не дозволяє скасувати ці події є Opera.

Як ви бачите в іншій моїй відповіді, перехоплення Ctrl+ vі Ctrl+ cмає багато побічних ефектів, і це все ще не заважає користувачам вставляти Editменю Firefox тощо.

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 все ще є незначні проблеми з цим методом (він очищає буфер обміну замість вирізання / копіювання, коли запобігає замовчуванню), але ця помилка, здається, виправлена ​​в Chrome.

Дивіться також: http://www.quirksmode.org/dom/events/cutcopypaste.html та пов’язану з цим тестову сторінку http://www.quirksmode.org/dom/events/tests/cutcopypaste.html для отримання додаткової інформації.


9

Демо-версія: 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!');
        }
    });

}); 

8

Коротке рішення щодо запобігання користувачеві використовувати контекстне меню, копіювати та вирізати jQuery:

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

Також вимкнення вибору тексту в 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;
}

4

Якщо ви використовуєте ctrlKeyвластивість, вам не потрібно підтримувати стан.

   $(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.
      } 
    }

ЦЕ правильна відповідь! Подія має властивість ctrlKey = true, якщо при цьому була натиснута клавіша. Нам не потрібні зайві події.
JanBrus

3

Я написав плагін jQuery, який ловить натискання клавіш. З його допомогою можна ввімкнути декілька мовних скриптів у формах html без ОС (крім шрифтів). Це близько 300 рядків коду, можливо, ви хочете подивитися:

Як правило, будьте обережні з подібними змінами. Я написав плагін для клієнта, оскільки інших рішень не було.


3

Ви можете використовувати цей код для виявлення та запобігання їх дії CTRL+ C, CTRL+ V, CTRL+ правою кнопкою мишіX

$(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();
    });

3

замість onkeypress використовуйте onkeydown.

<input type="text" onkeydown="if(event.ctrlKey && event.keyCode==86){return false;}" name="txt">

2

Інший підхід (не потрібен плагін) - це просто використовувати ctrlKeyвластивість об'єкта події, який передається. Він вказує, чи Ctrlбув натиснутий під час події, як це:

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

Дивіться також jquery: keypress, ctrl + c (або якесь подібне комбо) .


0

Не забувайте, що, хоча ви зможете виявити та заблокувати Ctrl+ C/ V, ви все одно можете змінити значення певного поля.
Найкращим прикладом для цього є функція Chrome Inspect Element, яка дозволяє змінювати властивість значення поля.


0

У мене вже є ваша проблема, і я вирішив її наступним кодом .., який приймає лише номери

$('#<%= 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;
            }
        });

ви можете виявити Ctrlідентифікаторe.which == 17


-1

Ви можете прослухати подію натискання клавіш і зупинити подію за замовчуванням (введення тексту), якщо вона відповідає конкретним кодам клавіш


-1

Важлива примітка

Я e.keyCodeдеякий час використовував, і я виявив, що, коли я натискаю ctrl+ ., цей атрибут повертає неправильне число, 190, а код ASCI .- 46!

Тому слід використовувати e.key.toUpperCase().charCodeAt(0)замість цього e.keyCode.


-4

Є кілька способів запобігти цьому.

Однак користувач завжди зможе вимкнути javascript або просто подивитися вихідний код сторінки.

Деякі приклади (потрібен 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;});

Редагувати: Як сказав Тім Даун, всі ці функції залежать від браузера.


2
У цьому є ряд проблем: по-перше, він не працюватиме в браузерах, у яких немає pasteподії, яка включає всі версії Firefox до версії 3. По-друге, window.clipboardDataце лише IE, і я вважаю, що він зараз за замовчуванням відключений в IE . По-третє, вимкнення всіх keydownподій, у яких натискається клавіша Ctrl, є надмірним: ви запобігаєте корисним комбінаціям клавіш, таким як Ctrl-A (виберіть усі) та Ctrl-Z (скасувати). По-четверте, як згадують інші, це дійсно погано робити.
Тім Даун

Ви маєте рацію з тим, що працює не в кожному браузері. Ніхто Блок ctrl насправді дратує. Було зручно один раз, коли клієнт хотів заблокувати поле "Підтвердження електронною поштою та паролем".
Густаво Кардосо,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.