Bagaimana cara mendeteksi Ctrl + V, Ctrl + C menggunakan JavaScript?

173

Bagaimana cara mendeteksi ctrl+ v, ctrl+ cmenggunakan Javascript?

Saya perlu membatasi menempel di textareas saya, pengguna akhir tidak boleh menyalin dan menempelkan konten, pengguna hanya harus mengetik teks di textarea.

Bagaimana cara mencapai ini?

Ramakrishnan
sumber
3
Apa tujuan dari ini? Dua skenario sah yang dapat saya pikirkan adalah kolom kata sandi (yang tidak dapat Anda salin) dan tes kecepatan mengetik. Saya yakin Anda dapat mendeteksi pengetikan cepat yang mencurigakan.
Paul Butcher
9
@Paul Butcher, @Pengeng: Ada skenario, di mana Anda membutuhkan ini. Contoh yang sangat sederhana: Situs untuk belajar bahasa asing. Efek pembelajaran ditingkatkan, jika Anda mengetik kata-kata dengan tangan alih-alih menggunakan salin & tempel.
back2dos
2
Situasi lain yang sah mungkin adalah di mana entri ganda diperlukan untuk mendeteksi kesalahan (mis. Ketik email Anda dua kali, sehingga kami tahu tidak ada kesalahan ketik di dalamnya). Namun, pengguna seperti itu mungkin menyimpan daftar alamat email yang dibuat secara acak (misalnya, sneakemail), dan mungkin ingin menempelkannya untuk keakuratan.
Paul Butcher
40
@Paul Butcher - itu sama sekali bukan situasi yang sah, saya benci situs yang melakukan itu dan saya selalu menyalin / menempel alamat email saya (panjang) dari satu input ke input lainnya. Memecah copy / paste adalah masalah kegunaan utama. Itu benar-benar melempar pengguna, karena itu sangat mendasar bagi model mental mereka sehingga mereka berharap untuk "hanya bekerja". Seolah-olah Anda mencoba menarik sebuah pintu dan pintu itu berayun menjauh dari Anda alih-alih ke arah Anda!
EMP
4
Setiap kali salinan seperti itu tidak diizinkan di halaman, apa yang saya lakukan adalah, menempelkan teks di tempat lain (saya menggunakan URL bar) dan kemudian Ctrl + A (pilih teks yang baru saja ditempelkan di url), seret dan lepaskan bidang di jelajah, tempat tempel dinonaktifkan. Saya kira, ini adalah sesuatu yang tidak dapat dicegah sampai hari ini.
Janakiram

Jawaban:

180

Saya hanya melakukan ini karena minat. Saya setuju itu bukan hal yang benar untuk dilakukan, tetapi saya pikir itu harus menjadi keputusan op ... Juga kode dapat dengan mudah diperluas untuk menambah fungsionalitas, daripada mengambilnya (seperti clipboard yang lebih maju, atau Ctrl+ smemicu server -selain hemat).

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

Juga hanya untuk memperjelas, skrip ini membutuhkan pustaka jQuery.

Demo codepen

EDIT: menghapus 3 baris berlebihan (melibatkan e.yang) berkat saran Tim Down (lihat komentar)

EDIT: menambahkan dukungan untuk Mac ( cmdbukan kunci ctrl)

jackocnr
sumber
4
Mengapa keydowndan keyuppenangannya aktif document? Anda dapat menguji tombol Ctrl di $(".no-copy-paste").keydownhandler. Juga, tidak perlu untuk e.keyCode || e.whichbit: e.keyCodebekerja di semua browser yang e.whichberfungsi, jadi e.whichtidak akan pernah digunakan. Mungkin Anda memikirkan bagaimana Anda mendapatkan kode karakter dari suatu keypressacara? Akhirnya, ini tidak akan melakukan apa pun tentang pasta dari konteks atau mengedit menu, tapi saya kira OP tidak bertanya langsung tentang itu.
Tim Down
@Tim: Penangan tombol Ctrl pada dokumen bersifat umum - karena mereka mungkin tidak ingin variabel ctrlDown secara eksklusif ditautkan ke input no-copy-paste. Ini mungkin OTT. Terima kasih atas tip e.which - Saya telah menghabiskan setengah jam meneliti berbagai kasus penggunaan e.keyCode dan e.which dengan keydown () dan penekanan tombol (), dan sungguh kacau (terutama di firefox)!
jackocnr
1
jackocnr: Saya merekomendasikan artikel penanganan kunci JavaScript Jan Wolter: unixpapa.com/js/key.html Saya sudah sering menggunakannya untuk referensi dan tidak menemukan kesalahan.
Tim Down
3
Kawan! Terima kasih! Inilah yang saya butuhkan untuk memungkinkan pengguna memilih "elemen" (entri kalender) di aplikasi web yang saya tulis, tekan ctrl + c untuk "menyalin", lalu ctrl + v untuk "menempelkan", semua tanpa benar-benar berinteraksi dengan papan klip yang diberkati. ctrl + c Saya ingat apa yang mereka klik, ctrl + v saya menduplikasinya, semua orang menang.
Dan F
2
Saya bukan ahli atau apa pun, tapi saya pikir mungkin akan lebih baik untuk menguji e.metaKeyatau e.ctrlKeymenjadi truealih - alih menetapkan nilai angka ke kunci dan menguji mereka.
Sluther
52

Dengan jquery Anda dapat dengan mudah mendeteksi salin, tempel, dll dengan mengikat fungsi:

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

Informasi lebih lanjut di sini: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/

Chris Andersson
sumber
1
Sayangnya, metode ini hanya akan diaktifkan pada Firefox jika teks dipilih
Yassir Ennazk
44

Meskipun bisa mengganggu ketika digunakan sebagai langkah anti-pembajakan, saya bisa melihat mungkin ada beberapa contoh di mana itu akan sah, jadi:

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
}

Saya telah menggunakan event.ctrlKeydaripada memeriksa kode kunci seperti pada sebagian besar browser di Mac OS X Ctrl/ Alt"turun" dan "naik" peristiwa tidak pernah dipicu, jadi satu-satunya cara untuk mendeteksi adalah dengan menggunakan event.ctrlKeydalam acara c misalnya setelah Ctrlkuncinya adalah diturunkan. Saya juga mengganti ctrlKeydengan metaKeyuntuk mac.

Keterbatasan metode ini:

  • Opera tidak mengizinkan penonaktifan acara klik kanan

  • Seret dan lepas di antara jendela browser tidak dapat dicegah sejauh yang saya tahu.

  • The edit-> copyitem menu di misalnya Firefox masih dapat memungkinkan copy / paste.

  • Juga tidak ada jaminan bahwa untuk orang-orang dengan tata letak keyboard / lokal yang berbeda yang menyalin / menempel / memotong adalah kode kunci yang sama (meskipun tata letak sering hanya mengikuti standar yang sama dengan bahasa Inggris), tetapi selimut "nonaktifkan semua tombol kontrol" berarti memilih semua dll juga akan dinonaktifkan jadi saya pikir itu kompromi yang perlu dibuat.
cryo
sumber
14

Ada cara lain untuk melakukan hal ini: onpaste , oncopydanoncut peristiwa dapat terdaftar dan dibatalkan pada IE, Firefox, Chrome, Safari (dengan beberapa masalah kecil), browser hanya utama yang tidak memungkinkan membatalkan peristiwa ini adalah Opera.

Seperti yang Anda lihat di jawaban saya yang lain, menyadap Ctrl+ vdan Ctrl+ cmemiliki banyak efek samping, dan itu masih tidak mencegah pengguna menyisipkan menggunakan Editmenu Firefox dll.

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 masih memiliki beberapa masalah kecil dengan metode ini (ini menghapus clipboard menggantikan cut / copy ketika mencegah default) tetapi bug itu tampaknya telah diperbaiki di Chrome sekarang.

Lihat juga: http://www.quirksmode.org/dom/events/cutcopypaste.html dan halaman pengujian terkait http://www.quirksmode.org/dom/events/tests/cutcopypaste.html untuk informasi lebih lanjut.

cryo
sumber
9

Demo Langsung: 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
sumber
8

Solusi singkat untuk mencegah pengguna menggunakan menu konteks, menyalin dan memotong jQuery:

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

Juga menonaktifkan pemilihan teks di CSS mungkin berguna:

.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
sumber
4

Jika Anda menggunakan ctrlKeyproperti, Anda tidak perlu mempertahankan status.

   $(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
sumber
INI jawaban yang benar! Acara memiliki properti ctrlKey = true jika tombol telah ditekan dengannya. Kami tidak membutuhkan acara tambahan.
JanBrus
3

Saya menulis plugin jQuery, yang menangkap penekanan tombol. Ini dapat digunakan untuk mengaktifkan input skrip berbagai bahasa dalam bentuk html tanpa OS (kecuali font). Sekitar 300 baris kode, mungkin Anda ingin melihatnya:

Secara umum, berhati-hatilah dengan perubahan seperti itu. Saya menulis plugin untuk klien karena solusi lain tidak tersedia.

miku
sumber
3

Anda dapat menggunakan kode ini untuk klik kanan, CTRL+ C, CTRL+ V, CTRL+ Xmendeteksi dan mencegah tindakan mereka

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

alih-alih menekan tombol, gunakan onkeydown.

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

Jangan lupa bahwa, meskipun Anda mungkin dapat mendeteksi dan memblokir Ctrl+ C/ V, Anda masih dapat mengubah nilai bidang tertentu.
Contoh terbaik untuk ini adalah fungsi Elemen Inspeksi Chrome, ini memungkinkan Anda untuk mengubah properti nilai suatu bidang.

BlueCacti
sumber
0

saya sudah memiliki masalah Anda dan saya menyelesaikannya dengan kode berikut .. yang hanya menerima angka

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

Anda dapat mendeteksi Ctrlide.which == 17

Amr Badawy
sumber
-1

Anda dapat mendengarkan acara penekanan tombol, dan menghentikan acara default (memasukkan teks) jika cocok dengan kode kunci tertentu.

balo
sumber
-1

Catatan penting

Saya menggunakan e.keyCodeuntuk sementara waktu dan saya mendeteksi bahwa ketika saya menekan ctrl+ ., atribut ini mengembalikan nomor yang salah, 190, sedangkan kode ascii .adalah 46!

Jadi sebaiknya Anda gunakan e.key.toUpperCase().charCodeAt(0)saja e.keyCode.

Amir Fo
sumber
-4

Ada beberapa cara untuk mencegahnya.

Namun, pengguna akan selalu dapat mematikan javascript atau hanya melihat pada kode sumber halaman.

Beberapa contoh (memerlukan 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;});

Sunting: Bagaimana Tim Down berkata, semua fungsi ini adalah tanggungan browser.

Gustavo Cardoso
sumber
2
Ini memiliki sejumlah masalah: pertama, itu tidak akan berfungsi di browser yang tidak memiliki pasteacara, yang mencakup semua versi Firefox sebelum versi 3. Kedua, window.clipboardDatahanya IE dan saya percaya sekarang dinonaktifkan secara default di IE . Ketiga, menonaktifkan semua keydownperistiwa di mana tombol Ctrl ditekan berlebihan: Anda mencegah pintasan keyboard yang bermanfaat seperti Ctrl-A (pilih semua) dan Ctrl-Z (batalkan). Keempat, seperti yang disebutkan oleh orang lain, ini adalah hal yang sangat buruk untuk dilakukan.
Tim Down
Anda benar bahwa itu tidak berfungsi pada setiap browser. Tidak ada. Blok ctrl memang sangat mengganggu. Itu berguna sekali ketika klien ingin memblokir bidang "Email Konfirmasi dan Kata Sandi".
Gustavo Cardoso