183

How to detect ctrl+v, ctrl+c using Javascript?

I need to restrict pasting in my textareas, end user should not copy and paste the content, user should only type text in textarea.

How to achieve this?

kqw
  • 17,649
  • 11
  • 61
  • 92
Ramakrishnan
  • 4,584
  • 9
  • 31
  • 39
  • 4
    What is the purpose of this? The only two legitimate scenarios I can think of are password fields (which you can't copy out of anyway) and a typing speed test. I'm sure you can detect suspiciously fast typing. – Paul Butcher May 25 '10 at 11:15
  • Yea, you probably should give your reasons or made up a legitimate reason. Such as the typing speed test...but even for that, I don't think a textarea would be the right control. – dotjoe May 25 '10 at 13:23
  • 10
    @Paul Butcher, @Propeng: There are scenarios, where you need this. Very simple example: A site for learning foreign languages. The learning effect is enhanced, if you type the words by hand instead of using copy & paste. – back2dos May 25 '10 at 13:55
  • 1
    Good point, but in a learning situation, this restriction needn't be enforced, because the user will want to type it in. It is only when testing, that you should ensure that the answers they are giving are actually entered by them, and even then, if they have access to an answer to copy & paste, they can equally well copy it in manually, so it doesn't help. – Paul Butcher May 25 '10 at 15:01
  • 2
    Another legitimate situation might be where double entry is required to detect mistakes (e.g. type your email in twice, so that we know it hasn't got a typo in it). Still, such a user might keep a list of randomly generated email addresses (e.g. sneakemail), and would probably want to paste it for accuracy. – Paul Butcher May 25 '10 at 15:08
  • 46
    @Paul Butcher - that is not a legitimate situation at all, I *hate* sites that do that and I *always* copy/paste my (long) email address from one input to the other. Breaking copy/paste is a major usability problem. It really throws the user off, because it's so fundamental to their mental model that they expect it to "just work". It's as if you tried to pull a door and it swung away from you instead of towards you! – EMP Jun 15 '10 at 05:21
  • 1
    Also would need to detect/restrict a right-click as well, to prevent pasting. – AVProgrammer Mar 25 '12 at 06:22
  • Needed for serious power programming of bioinformatics applications. Sheesh. – DragonLord Oct 19 '12 at 00:28
  • One reason to detect copy/paste (more so paste in my case) is to restrict the length of a field. I currently use keypress and check the length, but keypress isn't triggered when you use paste. It's nice to have it on keypress instead of writing a novel only to find out you ran out of space a long time ago. – Recognizer Apr 17 '13 at 18:21
  • What I'd like is a clean/simple way to PREVENT this detection. I utterly hate websites which add "check it out on URL" when I copy-paste some tidbit to friends. Too bad there is no "punch the writer" url. – Kheldar Feb 24 '14 at 12:13
  • 1
    don't forget the shift+insert combo – Matteo Oct 16 '14 at 07:27
  • 4
    Whenever such a copy paste it not allowed in a page, what I do is, paste the text somewhere else (I use the URL bar) and then Ctrl + A (select the text just pasted in the url ), drag and drop the the field in the browse, where paste is disabled. I guess, this is something not preventable as of today. – Janakiram Jan 01 '16 at 18:41
  • 1
    I believe I have a legitimate reason for you all. :) I am currently designing a webpage with a pseudo-unix interface, which is to say, a fake command line with only a few commands. In this case, I want ^C to act as it would on a command line, instead of pasting. --- That being said, reading this was valuable, and I will be sure to add in a way to let the user paste stuff. I can't think of when they would need to, but hey, I agree that sites which limit it are often problematic. --- Any way, cheers! – kirypto Sep 23 '16 at 03:53
  • One legit application I can think of is the verify field for passwords and email addresses: if you detect ctrl+v in the `name="email"`, you automatically copy over to the `name="repeat-email"`, and if you don't detect it, you disallow pasting in the verification field. – Joeytje50 Aug 09 '17 at 12:19

17 Answers17

192

I just did this out of interest. I agree it's not the right thing to do, but I think it should be the op's decision... Also the code could easily be extended to add functionality, rather than take it away (like a more advanced clipboard, or Ctrl+s triggering a server-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>

Also just to clarify, this script requires the jQuery library.

Codepen demo

EDIT: removed 3 redundant lines (involving e.which) thanks to Tim Down's suggestion (see comments)

EDIT: added support for Macs (cmd key instead of ctrl)

Misha Akopov
  • 9,542
  • 26
  • 54
  • 73
jackocnr
  • 15,220
  • 9
  • 51
  • 60
  • 4
    Why the `keydown` and `keyup` handlers on `document`? You can test for the Ctrl key in the `$(".no-copy-paste").keydown` handler. Also, there's no need for the `e.keyCode || e.which` bit: `e.keyCode` works in all browsers that `e.which` works in, so `e.which` will never be used. Perhaps you were thinking of how you get a character code from a `keypress` event? Finally, this will do nothing about pastes from the context or edit menus, but I suppose the OP didn't ask directly about that. – Tim Down May 25 '10 at 13:34
  • @Tim: Ctrl key handlers on document to be general - as they may not want the ctrlDown variable to be exclusively linked to the no-copy-paste input(s). This is perhaps OTT. Thanks for the e.which tip - I've since spent half an hour researching the different use cases of e.keyCode and e.which with keydown() and keypress(), and what a mess (especially in firefox)! – jackocnr May 25 '10 at 17:49
  • although this answers the question on how to detect ctrl-c and ctrl-v, other ways of pasting (rightclick-paste) are not (yet) detected this way. – Konerak May 25 '10 at 18:04
  • 1
    jackocnr: I recommend Jan Wolter's JavaScript key handling article: http://unixpapa.com/js/key.html I've used it for reference many times and not found an error. – Tim Down May 25 '10 at 18:30
  • 4
    Dude! Thanks! This is exactly what I needed to enable users to select an "element" (calendar entry) in a web app I'm writing, hit ctrl + c to "copy" it, then ctrl+v to "paste" it, all without actually interacting with the allmighty blessed clipboard. ctrl+c I remember what they're clicked on, ctrl+v I duplicate it, everyone wins. – Dan F May 02 '12 at 11:26
  • 2
    I'm not an expert or anything, but i think it would probably be better to test for `e.metaKey` or `e.ctrlKey` being `true` instead of assigning number values to the keys and testing those. – sluther Nov 28 '12 at 06:57
  • this wont work if you paste with right click and select paste – mkavici Jan 19 '14 at 16:29
  • Checkout this much more simple answer... http://stackoverflow.com/questions/4604057/jquery-keypress-ctrlc-or-some-combo-like-that – doublejosh Aug 06 '14 at 02:21
  • Don't forget us Mac users! You'll want to listen not just for Ctrl's code 17 but also Cmd (224). – Dan Jun 22 '16 at 12:55
52

With jquery you can easy detect copy, paste, etc by binding the function:

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

More information here: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/

Chris Andersson
  • 1,189
  • 9
  • 14
45

While it can be annoying when used as an anti-piracy measure, I can see there might be some instances where it'd be legitimate, so:

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
}

I've used event.ctrlKey rather than checking for the key code as on most browsers on Mac OS X Ctrl/Alt "down" and "up" events are never triggered, so the only way to detect is to use event.ctrlKey in the e.g. c event after the Ctrl key is held down. I've also substituted ctrlKey with metaKey for macs.

Limitations of this method:

  • Opera doesn't allow disabling right click events

  • Drag and drop between browser windows can't be prevented as far as I know.

  • The edit->copy menu item in e.g. Firefox can still allow copy/pasting.

  • There's also no guarantee that for people with different keyboard layouts/locales that copy/paste/cut are the same key codes (though layouts often just follow the same standard as English), but blanket "disable all control keys" mean that select all etc will also be disabled so I think that's a compromise which needs to be made.
udondan
  • 48,050
  • 17
  • 168
  • 161
cryo
  • 13,061
  • 4
  • 29
  • 34
14

There's another way of doing this: onpaste, oncopy and oncut events can be registered and cancelled in IE, Firefox, Chrome, Safari (with some minor problems), the only major browser that doesn't allow cancelling these events is Opera.

As you can see in my other answer intercepting Ctrl+v and Ctrl+c comes with many side effects, and it still doesn't prevent users from pasting using the Firefox Edit menu etc.

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 still has some minor problems with this method (it clears the clipboard in place of cut/copy when preventing default) but that bug appears to have been fixed in Chrome now.

See also: http://www.quirksmode.org/dom/events/cutcopypaste.html and the associated test page http://www.quirksmode.org/dom/events/tests/cutcopypaste.html for more information.

udondan
  • 48,050
  • 17
  • 168
  • 161
cryo
  • 13,061
  • 4
  • 29
  • 34
9

Live Demo : 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
  • 64,884
  • 28
  • 201
  • 207
8

Short solution for preventing user from using context menu, copy and cut in jQuery:

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

Also disabling text selection in CSS might come handy:

.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
  • 81
  • 1
  • 1
7

If you use the ctrlKey property, you don't need to maintain state.

   $(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
  • 31,452
  • 56
  • 235
  • 393
  • THIS is the correct answer! The event has a property ctrlKey = true if a key has been pressed with it. We do not need any extra events. – JanBrus Jan 29 '20 at 09:56
3

instead of onkeypress, use onkeydown.

<input type="text" onkeydown="if(event.ctrlKey && event.keyCode==86){return false;}" name="txt">
atiruz
  • 2,461
  • 22
  • 34
3

I wrote a jQuery plugin, which catches keystrokes. It can be used to enable multiple language script input in html forms without the OS (except the fonts). Its about 300 lines of code, maybe you like to take a look:

Generally, be careful with such kind of alterations. I wrote the plugin for a client because other solutions weren't available.

miku
  • 161,705
  • 45
  • 286
  • 300
3

You can use this code for rightclick, CTRL+C, CTRL+V, CTRL+X detect and prevent their action

$(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();
    });
Mwiza
  • 4,494
  • 2
  • 33
  • 30
Varun Naharia
  • 4,836
  • 7
  • 42
  • 73
3

Another approach (no plugin needed) it to just use ctrlKey property of the event object that gets passed in. It indicates if Ctrl was pressed at the time of the event, like this:

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

See also jquery: keypress, ctrl+c (or some combo like that).

clemens
  • 14,173
  • 11
  • 38
  • 52
0

Don't forget that, while you might be able to detect and block Ctrl+C/V, you can still alter the value of a certain field.
Best example for this is Chrome's Inspect Element function, this allows you to change the value-property of a field.

udondan
  • 48,050
  • 17
  • 168
  • 161
BlueCacti
  • 8,169
  • 3
  • 18
  • 24
0

i already have your problem and i solved it by the following code .. that accept only numbers

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

you can detect Ctrl id e.which == 17

udondan
  • 48,050
  • 17
  • 168
  • 161
Amr Badawy
  • 6,805
  • 12
  • 46
  • 81
0

A hook that allows for overriding copy events, could be used for doing the same with paste events. The input element cannot be display: none; or visibility: hidden; sadly

export const useOverrideCopy = () => {
  const [copyListenerEl, setCopyListenerEl] = React.useState(
    null as HTMLInputElement | null
  )
  const [, setCopyHandler] = React.useState<(e: ClipboardEvent) => void | null>(
    () => () => {}
  )
  // appends a input element to the DOM, that will be focused.
  // when using copy/paste etc, it will target focused elements
  React.useEffect(() => {
    const el = document.createElement("input")  
    // cannot focus a element that is not "visible" aka cannot use display: none or visibility: hidden
    el.style.width = "0"
    el.style.height = "0"
    el.style.opacity = "0"
    el.style.position = "fixed"
    el.style.top = "-20px"
    document.body.appendChild(el)
    setCopyListenerEl(el)
    return () => {
      document.body.removeChild(el)
    }
  }, [])
  // adds a event listener for copying, and removes the old one 
  const overrideCopy = (newOverrideAction: () => any) => {
    setCopyHandler((prevCopyHandler: (e: ClipboardEvent) => void) => {
      const copyHandler = (e: ClipboardEvent) => {
        e.preventDefault()
        newOverrideAction()
      }
      copyListenerEl?.removeEventListener("copy", prevCopyHandler)
      copyListenerEl?.addEventListener("copy", copyHandler)
      copyListenerEl?.focus() // when focused, all copy events will trigger listener above
      return copyHandler
    })
  }
  return { overrideCopy }
}

Used like this:

const customCopyEvent = () => {
    console.log("doing something")
} 
const { overrideCopy } = useOverrideCopy()
overrideCopy(customCopyEvent)

Every time you call overrideCopy it will refocus and call your custom event on copy.

Gabriel Petersson
  • 2,079
  • 12
  • 20
-1

You can listen to the keypress event, and halt the default event (entering the text) if it matches the specific keycodes

baloo
  • 7,181
  • 4
  • 24
  • 35
-1

Important note

I was using e.keyCode for a while and i detected that when i press ctrl + ., This attribute returns a wrong number, 190, while the ascii code of . is 46!

So you should use e.key.toUpperCase().charCodeAt(0) instead of e.keyCode.

Amir Fo
  • 3,044
  • 1
  • 25
  • 36
-4

There is some ways to prevent it.

However the user will be always able to turn the javascript off or just look on the source code of the page.

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

Edit: How Tim Down said, this functions are all browser dependents.

Gustavo Cardoso
  • 737
  • 2
  • 7
  • 20
  • 2
    This has a number of problems: first, it won't work in browsers that don't have a `paste` event, which includes all versions of Firefox prior to version 3. Second, `window.clipboardData` is IE only and I believe is now disabled by default in IE. Third, disabling all `keydown` events where the Ctrl key is pressed is excessive: you prevent useful keyboard shortcuts such as Ctrl-A (select all) and Ctrl-Z (undo). Fourth, as mentioned by others, this is a really bad thing to do. – Tim Down May 25 '10 at 11:25
  • You are right about that don't working on every browser. Nobody The ctrl block is annoying indeed. It was handy once when a client wanted to block the "Confirmation Email and Password" field. – Gustavo Cardoso May 25 '10 at 11:38