วิธีการตรวจหา Ctrl + V, Ctrl + C โดยใช้ JavaScript?


173

วิธีตรวจจับctrl+ v, ctrl+ cโดยใช้ Javascript

ฉันต้องการ จำกัด การวางข้อความใน textareas ของฉันผู้ใช้ไม่ควรคัดลอกและวางเนื้อหาผู้ใช้ควรพิมพ์ข้อความใน textarea เท่านั้น

ทำอย่างไรจึงจะได้สิ่งนี้?


3
จุดประสงค์ของสิ่งนี้คืออะไร? สถานการณ์ที่ถูกกฎหมายเพียงสองข้อเท่านั้นที่ฉันสามารถนึกได้ก็คือฟิลด์รหัสผ่าน (ซึ่งคุณไม่สามารถคัดลอกออกมาได้) และการทดสอบความเร็วในการพิมพ์ ฉันแน่ใจว่าคุณสามารถตรวจจับการพิมพ์ที่รวดเร็วอย่างน่าสงสัย
Paul Butcher

9
@Paul Butcher, @Propeng: มีสถานการณ์ที่คุณต้องการสิ่งนี้ ตัวอย่างที่ง่ายมาก: เว็บไซต์สำหรับการเรียนรู้ภาษาต่างประเทศ ผลการเรียนรู้จะได้รับการปรับปรุงหากคุณพิมพ์คำด้วยมือแทนการใช้คัดลอกและวาง
back2dos

2
อีกสถานการณ์ที่ถูกกฎหมายอาจเป็นสิ่งที่จำเป็นต้องใช้ double entry เพื่อตรวจสอบข้อผิดพลาด (เช่นพิมพ์อีเมลของคุณเป็นสองครั้งเพื่อให้เรารู้ว่ามันไม่ได้พิมพ์ผิดในนั้น) อย่างไรก็ตามผู้ใช้ดังกล่าวอาจเก็บรายการที่อยู่อีเมลที่สร้างแบบสุ่ม (เช่น sneakemail) และอาจต้องการวางเพื่อความถูกต้อง
พอล Butcher

40
@ Paul Butcher - นั่นไม่ใช่สถานการณ์ที่ถูกต้องเลยฉันเกลียดไซต์ที่ทำเช่นนั้นและฉันมักจะคัดลอก / วางที่อยู่อีเมล (ยาว) ของฉันจากอินพุตหนึ่งไปยังอีกอันหนึ่ง การคัดลอก / วางเป็นปัญหาสำคัญในการใช้งาน มันเป็นการทิ้งผู้ใช้ออกไปจริงๆเพราะมันเป็นพื้นฐานของโมเดลจิตที่พวกเขาคาดหวังให้มัน "ทำงานได้" ราวกับว่าคุณพยายามที่จะดึงประตูและมันเหวี่ยงออกไปจากคุณแทนที่จะเข้าหาคุณ!
EMP

4
เมื่อใดก็ตามที่การคัดลอกวางไม่ได้รับอนุญาตในหน้าสิ่งที่ฉันทำคือวางข้อความที่อื่น (ฉันใช้แถบ URL) แล้วกด Ctrl + A (เลือกข้อความที่เพิ่งวางใน url) ลากและวาง ในการเรียกดูโดยที่ปิดการใช้งานการวาง ฉันเดาว่านี่เป็นสิ่งที่ไม่สามารถป้องกันได้ในปัจจุบัน
Janakiram

คำตอบ:


180

ฉันเพิ่งทำสิ่งนี้ออกมาจากความสนใจ ฉันยอมรับว่ามันไม่ใช่สิ่งที่ถูกต้องที่จะทำ แต่ฉันคิดว่ามันควรเป็นการตัดสินใจของ op ... นอกจากนี้โค้ดสามารถขยายได้อย่างง่ายดายเพื่อเพิ่มฟังก์ชันการทำงานแทนที่จะนำออกไป (เช่นคลิปบอร์ดขั้นสูงหรือ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

แก้ไข: ลบ 3 บรรทัดที่ซ้ำซ้อน (เกี่ยวข้องกับ e.which) ขอบคุณคำแนะนำของ Tim Down (ดูความคิดเห็น)

แก้ไข: เพิ่มการสนับสนุนสำหรับ Mac ( cmdกุญแจแทนctrl)


4
ทำไมkeydownและkeyupจัดการกับdocument? คุณสามารถทดสอบปุ่ม Ctrl ใน$(".no-copy-paste").keydownตัวจัดการ นอกจากนี้ไม่จำเป็นต้องมีe.keyCode || e.whichบิต: ใช้e.keyCodeงานได้ในเบราว์เซอร์ทั้งหมดที่e.whichทำงานได้ดังนั้นe.whichจะไม่ถูกนำมาใช้ บางทีคุณอาจกำลังคิดว่าจะรับรหัสอักขระจากkeypressเหตุการณ์ได้อย่างไร ในที่สุดสิ่งนี้จะไม่ทำอะไรเกี่ยวกับน้ำพริกจากบริบทหรือเมนูแก้ไข แต่ฉันคิดว่า OP ไม่ได้ถามเกี่ยวกับสิ่งนั้นโดยตรง
ทิมลง

@Tim: ตัวจัดการคีย์ Ctrl บนเอกสารเป็นเรื่องทั่วไปเนื่องจากอาจไม่ต้องการให้ตัวแปร ctrlDown เชื่อมโยงกับอินพุตที่ไม่คัดลอกวางเท่านั้น นี่อาจจะเป็น OTT ขอบคุณสำหรับเคล็ดลับ e.which - ฉันใช้เวลาครึ่งชั่วโมงในการค้นคว้ากรณีการใช้ที่แตกต่างกันของ 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 ฉันทำซ้ำทุกคนชนะ
Dan F

2
ฉันไม่ใช่ผู้เชี่ยวชาญหรืออะไร แต่ฉันคิดว่ามันน่าจะดีกว่าที่จะทดสอบe.metaKeyหรือe.ctrlKeyเป็นtrueแทนที่จะกำหนดค่าตัวเลขให้กับคีย์และทดสอบเหล่านั้น
sluther

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"down" และ "up" ไม่เคยถูกเรียกดังนั้นวิธีเดียวที่จะตรวจจับคือใช้event.ctrlKeyในเหตุการณ์เช่น c หลังจากCtrlคีย์คือ จัดขึ้น ฉันยังทดแทนctrlKeyด้วยmetaKeyสำหรับ macs

ข้อ จำกัด ของวิธีนี้:

  • Opera ไม่อนุญาตให้ปิดใช้งานกิจกรรมคลิกขวา

  • การลากและวางระหว่างหน้าต่างเบราว์เซอร์ไม่สามารถป้องกันได้เท่าที่ฉันรู้

  • edit-> copyรายการเมนูในเช่น Firefox ยังคงสามารถอนุญาตให้คัดลอก / วาง

  • นอกจากนี้ยังไม่มีการรับประกันว่าสำหรับผู้ที่มีรูปแบบแป้นพิมพ์ / ตำแหน่งที่ตั้งที่คัดลอก / วาง / ตัดเป็นรหัสคีย์เดียวกัน (แม้ว่ารูปแบบมักจะเป็นไปตามมาตรฐานเดียวกับภาษาอังกฤษ) แต่ครอบคลุม "ปิดใช้งานปุ่มควบคุมทั้งหมด" หมายความว่าเลือกทั้งหมด ฯลฯ จะถูกปิดการใช้งานด้วยดังนั้นฉันคิดว่านั่นเป็นการประนีประนอมซึ่งจำเป็นต้องทำ

14

มีวิธีการทำเช่นนี้ผู้อื่น: onpaste , oncopyและoncutเหตุการณ์ที่เกิดขึ้นสามารถลงทะเบียนและยกเลิกใน IE, Firefox, Chrome, Safari (ที่มีปัญหาเล็ก ๆ น้อย ๆ บางคน), เบราว์เซอร์เท่านั้นที่สำคัญที่ไม่อนุญาตให้มีการยกเลิกเหตุการณ์เหล่านี้เป็นโอเปร่า

อย่างที่คุณเห็นในคำตอบอื่น ๆ ของฉันการสกัดกั้น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สำหรับข้อมูลเพิ่มเติม



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


2

วิธีการอื่น (ไม่จำเป็นต้องใช้ปลั๊กอิน) เพียงแค่ใช้ctrlKeyคุณสมบัติของวัตถุเหตุการณ์ที่ได้รับการส่งผ่านซึ่งบ่งชี้ว่าCtrlมีการกดในช่วงเวลาของเหตุการณ์เช่นนี้:

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

ดูเพิ่มเติมjQuery: ปุ่มกด CTRL + C (หรือคำสั่งผสมบางเช่นนั้น)


0

อย่าลืมว่าแม้ว่าคุณจะสามารถตรวจจับและบล็อกCtrl+ C/ ได้Vแต่คุณยังสามารถเปลี่ยนค่าของฟิลด์ที่ต้องการได้
ตัวอย่างที่ดีที่สุดสำหรับสิ่งนี้คือฟังก์ชั่นองค์ประกอบการตรวจสอบของ Chrome ซึ่งจะช่วยให้คุณเปลี่ยนคุณสมบัติค่าของฟิลด์


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

คุณสามารถตรวจสอบCtrlIDe.which == 17


-1

คุณสามารถฟังเหตุการณ์ keypress และหยุดเหตุการณ์เริ่มต้น (ป้อนข้อความ) หากตรงกับรหัสเฉพาะ


-1

โน๊ตสำคัญ

ฉันใช้ไปe.keyCodeระยะหนึ่งและฉันตรวจพบว่าเมื่อฉันกดctrl+ .คุณลักษณะนี้จะส่งกลับหมายเลขผิด 190 ในขณะที่รหัส ASCII ของ.46!

ดังนั้นคุณควรใช้แทนe.key.toUpperCase().charCodeAt(0)e.keyCode


-4

มีวิธีป้องกันบางอย่าง

อย่างไรก็ตามผู้ใช้จะสามารถปิดจาวาสคริปต์หรือดูที่ซอร์สโค้ดของหน้า

ตัวอย่างบางส่วน (ต้องการ 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;});

แก้ไข: วิธีที่ Tim Down พูดว่าฟังก์ชั่นนี้เป็นสิ่งที่พึ่งพาเบราว์เซอร์


2
สิ่งนี้มีปัญหาหลายอย่าง: อันดับแรกมันจะไม่ทำงานในเบราว์เซอร์ที่ไม่มีpasteเหตุการณ์ซึ่งรวมถึง Firefox ทุกเวอร์ชันก่อนหน้ารุ่นที่ 3 ที่สองwindow.clipboardDataคือ IE เท่านั้นและฉันเชื่อว่าตอนนี้ถูกปิดใช้งานโดยค่าเริ่มต้นใน IE . ประการที่สามการปิดใช้งานkeydownกิจกรรมทั้งหมดที่กดปุ่ม Ctrl มากเกินไป: คุณป้องกันแป้นพิมพ์ลัดที่มีประโยชน์เช่น Ctrl-A (เลือกทั้งหมด) และ Ctrl-Z (เลิกทำ) ข้อสี่ตามที่คนอื่น ๆ พูดถึงนี่เป็นสิ่งที่เลวร้ายจริงๆที่ต้องทำ
Tim Down

คุณพูดถูกว่าเบราว์เซอร์ทุกตัวไม่ทำงาน ไม่มีใครบล็อก ctrl นั้นน่ารำคาญอย่างแน่นอน สะดวกเมื่อลูกค้าต้องการบล็อกช่อง "อีเมลยืนยันและรหัสผ่าน"
Gustavo Cardoso
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.