Làm cách nào để phát hiện Ctrl + V, Ctrl + C bằng JavaScript?


173

Làm cách nào để phát hiện ctrl+ v, ctrl+ cbằng Javascript?

Tôi cần hạn chế dán trong textareas của mình, người dùng cuối không nên sao chép và dán nội dung, người dùng chỉ nên gõ văn bản trong textarea.

Làm thế nào để đạt được điều này?


3
mục đích của việc này là gì? Hai tình huống hợp pháp duy nhất tôi có thể nghĩ đến là các trường mật khẩu (dù sao bạn cũng không thể sao chép) và kiểm tra tốc độ đánh máy. Tôi chắc chắn rằng bạn có thể phát hiện gõ nhanh đáng ngờ.
Paul Butcher

9
@Paul Butcher, @Propeng: Có những kịch bản, nơi bạn cần điều này. Ví dụ rất đơn giản: Một trang web để học ngoại ngữ. Hiệu quả học tập được nâng cao, nếu bạn gõ các từ bằng tay thay vì sử dụng bản sao và dán.
back2dos

2
Một tình huống hợp pháp khác có thể là khi yêu cầu nhập kép để phát hiện lỗi (ví dụ: nhập email của bạn thành hai lần, để chúng tôi biết rằng nó không có lỗi đánh máy trong đó). Tuy nhiên, người dùng như vậy có thể giữ một danh sách các địa chỉ email được tạo ngẫu nhiên (ví dụ: sneakemail) và có thể muốn dán nó cho chính xác.
Paul Butcher

40
@Paul Butcher - đó hoàn toàn không phải là một tình huống hợp pháp, tôi ghét các trang web làm điều đó và tôi luôn sao chép / dán địa chỉ email (dài) của mình từ đầu vào này sang đầu vào khác. Phá vỡ sao chép / dán là một vấn đề khả năng sử dụng chính. Nó thực sự ném người dùng đi, bởi vì nó rất cơ bản đối với mô hình tinh thần của họ đến mức họ mong đợi nó "chỉ hoạt động". Cứ như thể bạn cố kéo một cánh cửa và nó quay ra khỏi bạn thay vì hướng về phía bạn!
EMP

4
Bất cứ khi nào một bản sao như vậy dán nó không được phép trong một trang, những gì tôi làm là, dán văn bản vào một nơi khác (tôi sử dụng thanh URL) và sau đó Ctrl + A (chọn văn bản vừa dán trong url), kéo và thả trường trong trình duyệt, nơi dán bị vô hiệu hóa. Tôi đoán, đây là một cái gì đó không thể ngăn chặn như ngày nay.
Janakiram

Câu trả lời:


180

Tôi chỉ làm điều này vì lợi ích. Tôi đồng ý nó không phải là điều đúng đắn nên làm, nhưng tôi nghĩ rằng nó phải được quyết định của op ... Ngoài ra mã một cách dễ dàng có thể được mở rộng thêm chức năng, chứ không phải mang nó đi (như một clipboard cao cấp hơn, hoặc Ctrl+ skích hoạt một máy chủ tiết kiệm bên).

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

Cũng chỉ để làm rõ, tập lệnh này yêu cầu thư viện jQuery.

Bản demo Codepen

EDIT: đã xóa 3 dòng thừa (liên quan đến e.which) nhờ đề xuất của Tim Down (xem bình luận)

EDIT: thêm hỗ trợ cho máy Mac ( cmdphím thay vì ctrl)


4
Tại sao keydownkeyupxử lý trên document? Bạn có thể kiểm tra phím Ctrl trong $(".no-copy-paste").keydowntrình xử lý. Ngoài ra, không cần e.keyCode || e.whichbit: e.keyCodehoạt động trong tất cả các trình duyệt e.whichhoạt động, vì vậy e.whichsẽ không bao giờ được sử dụng. Có lẽ bạn đã nghĩ về cách bạn có được một mã nhân vật từ một keypresssự kiện? Cuối cùng, điều này sẽ không làm gì với bột nhão từ ngữ cảnh hoặc chỉnh sửa menu, nhưng tôi cho rằng OP đã không hỏi trực tiếp về điều đó.
Tim xuống

@Tim: Trình xử lý phím Ctrl trên tài liệu là chung - vì chúng có thể không muốn biến ctrlDown được liên kết riêng với (các) đầu vào không sao chép-dán. Đây có lẽ là OTT. Cảm ơn về mẹo của e.which - Tôi đã dành nửa giờ để nghiên cứu các trường hợp sử dụng khác nhau của e.keyCode và e.which với keydown () và keypress () và một mớ hỗn độn (đặc biệt là trong firefox)!
jackocnr

1
jackocnr: Tôi đề xuất bài viết xử lý khóa JavaScript của Jan Wolter: unixpapa.com/js/key.html Tôi đã sử dụng nó để tham khảo nhiều lần và không tìm thấy lỗi.
Tim Down

3
Anh bạn! Cảm ơn! Đây chính xác là những gì tôi cần để cho phép người dùng chọn một "phần tử" (mục lịch) trong ứng dụng web tôi đang viết, nhấn ctrl + c để "sao chép" nó, sau đó ctrl + v để "dán" nó, tất cả mà không cần thực sự tương tác với clipboard tạm thời toàn năng. ctrl + c Tôi nhớ những gì họ đã nhấp vào, ctrl + v Tôi nhân đôi nó, mọi người đều thắng.
Dan F

2
Tôi không phải là một chuyên gia hay bất cứ điều gì, nhưng tôi nghĩ rằng nó có lẽ sẽ tốt hơn để thử nghiệm cho e.metaKeyhay e.ctrlKeytruethay vì gán giá trị số cho các phím và thử nghiệm những.
đĩ

52

Với jquery bạn có thể dễ dàng phát hiện sao chép, dán, vv bằng cách ràng buộc chức năng:

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

Thêm thông tin ở đây: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/


1
Thật không may, phương pháp này sẽ chỉ kích hoạt trên Firefox nếu văn bản được chọn
Yassir Ennazk

44

Mặc dù có thể gây phiền nhiễu khi được sử dụng như một biện pháp chống vi phạm bản quyền, tôi có thể thấy có thể có một số trường hợp hợp pháp, vì vậy:

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
}

Tôi đã sử dụng event.ctrlKeythay vì kiểm tra mã khóa như trên hầu hết các trình duyệt trên Mac OS X Ctrl/ Altcác sự kiện "xuống" và "lên" không bao giờ được kích hoạt, vì vậy cách duy nhất để phát hiện là sử dụng event.ctrlKeytrong sự kiện c sau khi Ctrlkhóa là giữ Tôi cũng đã thay ctrlKeybằng metaKeycho Mac.

Hạn chế của phương pháp này:

  • Opera không cho phép vô hiệu hóa các sự kiện nhấp chuột phải

  • Kéo và thả giữa các cửa sổ trình duyệt không thể được ngăn chặn theo như tôi biết.

  • Mục menu edit>> copytrong ví dụ Firefox vẫn có thể cho phép sao chép / dán.

  • Cũng không có gì đảm bảo rằng với những người có bố cục / vị trí bàn phím khác nhau sao chép / dán / cắt là cùng một mã khóa (mặc dù bố cục thường chỉ tuân theo cùng một tiêu chuẩn như tiếng Anh), nhưng "vô hiệu hóa tất cả các phím điều khiển" có nghĩa là chọn tất cả, v.v. cũng sẽ bị vô hiệu hóa vì vậy tôi nghĩ đó là một sự thỏa hiệp cần phải được thực hiện.

14

Có một cách khác để làm điều này: onpaste , oncopyoncutcác sự kiện có thể được đăng ký và hủy trong IE, Firefox, Chrome, Safari (với một số vấn đề nhỏ), trình duyệt lớn duy nhất mà không cho phép hủy bỏ những sự kiện này là Opera.

Như bạn có thể thấy trong câu trả lời khác của tôi, chặn Ctrl+ vCtrl+ cđi kèm với nhiều tác dụng phụ và nó vẫn không ngăn người dùng dán bằng Editmenu Firefox, v.v.

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 vẫn có một số vấn đề nhỏ với phương pháp này (nó xóa bảng tạm thay thế cho việc cắt / sao chép khi ngăn mặc định) nhưng lỗi đó dường như đã được sửa trong Chrome.

Xem thêm: http://www.quirksmode.org/dom/events/cutcopypaste.html và trang thử nghiệm liên quan http://www.quirksmode.org/dom/events/tests/cutcopypaste.html để biết thêm thông tin.


9

Bản trình diễn trực tiếp: 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

Giải pháp ngắn để ngăn người dùng sử dụng menu ngữ cảnh, sao chép và cắt trong jQuery:

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

Ngoài ra, vô hiệu hóa lựa chọn văn bản trong CSS có thể có ích:

.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

Nếu bạn sử dụng ctrlKeytài sản, bạn không cần phải duy trì trạng thái.

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

Đây là câu trả lời chính xác! Sự kiện này có thuộc tính ctrlKey = true nếu một phím đã được nhấn với nó. Chúng tôi không cần thêm bất kỳ sự kiện nào.
JanBrus

3

Tôi đã viết một plugin jQuery, bắt các tổ hợp phím. Nó có thể được sử dụng để cho phép nhập nhiều tập lệnh ngôn ngữ ở dạng html mà không cần HĐH (ngoại trừ phông chữ). Đó là khoảng 300 dòng mã, có thể bạn muốn xem qua:

Nói chung, hãy cẩn thận với các loại thay đổi như vậy. Tôi đã viết plugin cho khách hàng vì các giải pháp khác không có sẵn.


3

Bạn có thể sử dụng mã này để nhấp chuột phải, CTRL+ C, CTRL+ V, CTRL+ Xphát hiện và ngăn chặn hành động của họ

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

thay vì onkeypress, sử dụng onkeydown.

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


0

Đừng quên rằng, trong khi bạn có thể phát hiện và chặn Ctrl+ C/ V, bạn vẫn có thể thay đổi giá trị của một trường nhất định.
Ví dụ tốt nhất cho điều này là chức năng Kiểm tra phần tử của Chrome, điều này cho phép bạn thay đổi thuộc tính giá trị của một trường.


0

tôi đã có vấn đề của bạn và tôi đã giải quyết nó bằng đoạn mã sau .. chỉ chấp nhận số

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

bạn có thể phát hiện Ctrlide.which == 17


-1

Bạn có thể nghe sự kiện nhấn phím và tạm dừng sự kiện mặc định (nhập văn bản) nếu nó phù hợp với các mã phím cụ thể


-1

Lưu ý quan trọng

Tôi đã sử dụng được e.keyCodemột lúc và tôi phát hiện ra rằng khi tôi nhấn ctrl+ ., thuộc tính này trả về một số sai, 190, trong khi mã ascii .là 46!

Vì vậy, bạn nên sử dụng e.key.toUpperCase().charCodeAt(0)thay vì e.keyCode.


-4

Có một số cách để ngăn chặn nó.

Tuy nhiên, người dùng sẽ luôn có thể tắt javascript hoặc chỉ cần nhìn vào mã nguồn của trang.

Một số ví dụ (yêu cầu 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;});

Chỉnh sửa: Làm thế nào Tim Down nói, chức năng này là tất cả phụ thuộc trình duyệt.


2
Điều này có một số vấn đề: thứ nhất, nó sẽ không hoạt động trong các trình duyệt không có pastesự kiện, bao gồm tất cả các phiên bản Firefox trước phiên bản 3. Thứ hai, window.clipboardDatachỉ có IE và tôi tin rằng hiện bị tắt theo mặc định trong IE . Thứ ba, vô hiệu hóa tất cả các keydownsự kiện khi nhấn phím Ctrl là quá mức: bạn ngăn các phím tắt hữu ích như Ctrl-A (chọn tất cả) và Ctrl-Z (hoàn tác). Thứ tư, như đã đề cập bởi những người khác, đây là một điều thực sự xấu.
Tim xuống

Bạn đúng về điều đó không hoạt động trên mọi trình duyệt. Không ai Khối ctrl thực sự gây phiền nhiễu. Nó rất hữu ích khi khách hàng muốn chặn trường "Email xác nhận và mật khẩu".
Gustavo Cardoso
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.