¿Cómo detectar Ctrl + V, Ctrl + C usando JavaScript?

173

¿Cómo detectar ctrl+ v, ctrl+ cusando Javascript?

Necesito restringir el pegado en mis áreas de texto, el usuario final no debe copiar y pegar el contenido, el usuario solo debe escribir texto en el área de texto.

¿Cómo lograr esto?

Ramakrishnan
fuente
3
¿Cuál es el propósito de esto? Los únicos dos escenarios legítimos que se me ocurren son los campos de contraseña (que de todos modos no se pueden copiar) y una prueba de velocidad de escritura. Estoy seguro de que puede detectar una escritura sospechosamente rápida.
Paul Butcher
9
@Paul Butcher, @Propeng: Hay escenarios en los que necesitas esto. Ejemplo muy simple: un sitio para aprender idiomas extranjeros. El efecto de aprendizaje se mejora si escribe las palabras a mano en lugar de usar copiar y pegar.
back2dos
2
Otra situación legítima podría ser donde se requiere una doble entrada para detectar errores (por ejemplo, escriba su correo electrónico dos veces, para que sepamos que no tiene un error tipográfico). Aún así, dicho usuario podría mantener una lista de direcciones de correo electrónico generadas aleatoriamente (por ejemplo, sneakemail), y probablemente querría pegarla para mayor precisión.
Paul Butcher
40
@Paul Butcher: esa no es una situación legítima, odio los sitios que hacen eso y siempre copio / pego mi (larga) dirección de correo electrónico de una entrada a la otra. Romper copiar / pegar es un importante problema de usabilidad. Realmente asusta al usuario, porque es tan fundamental para su modelo mental que esperan que "simplemente funcione". ¡Es como si trataras de tirar de una puerta y se alejó de ti en lugar de hacia ti!
EMP
44
Siempre que tal copia pegar no esté permitida en una página, lo que hago es pegar el texto en otro lugar (uso la barra de URL) y luego Ctrl + A (seleccione el texto que acaba de pegar en la url), arrastre y suelte el campo en el navegador, donde pegar está deshabilitado. Supongo que esto es algo que no se puede prevenir a partir de hoy.
Janakiram

Respuestas:

180

Acabo de hacer esto por interés. Estoy de acuerdo en que no es lo correcto, pero creo que debería ser la decisión del operador ... Además, el código podría extenderse fácilmente para agregar funcionalidad, en lugar de eliminarlo (como un portapapeles más avanzado o Ctrl+ sactivar un servidor lado guardado).

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

También para aclarar, este script requiere la biblioteca jQuery.

Codepen demo

EDITAR: eliminó 3 líneas redundantes (que involucran e.which) gracias a la sugerencia de Tim Down (ver comentarios)

EDITAR: soporte agregado para Mac ( cmdclave en lugar de ctrl)

jackocnr
fuente
44
¿Por qué el keydowny los keyupcontroladores en document? Puede probar la tecla Ctrl en el $(".no-copy-paste").keydowncontrolador. Además, no es necesario el e.keyCode || e.whichbit: e.keyCodefunciona en todos los navegadores que e.whichfuncionan, por e.whichlo que nunca se utilizará. ¿Quizás estabas pensando en cómo obtienes un código de personaje de un keypressevento? Finalmente, esto no hará nada sobre las pastas del contexto o los menús de edición, pero supongo que el OP no preguntó directamente sobre eso.
Tim Down
@Tim: los controladores de teclas Ctrl en el documento son generales, ya que es posible que no deseen que la variable ctrlDown esté vinculada exclusivamente a las entradas sin copiar y pegar. Esto es quizás OTT. Gracias por el consejo de e.which: desde entonces he pasado media hora investigando los diferentes casos de uso de e.keyCode y e.which con keydown () y keypress (), ¡y qué desastre (especialmente en firefox)!
jackocnr
1
jackocnr: Recomiendo el artículo de manejo de claves JavaScript de Jan Wolter: unixpapa.com/js/key.html Lo he usado como referencia muchas veces y no he encontrado ningún error.
Tim Down
3
¡Tipo! ¡Gracias! Esto es exactamente lo que necesitaba para permitir a los usuarios seleccionar un "elemento" (entrada de calendario) en una aplicación web que estoy escribiendo, presionar ctrl + c para "copiarlo", luego ctrl + v para "pegarlo", todo sin en realidad interactuando con el portapapeles bendito todopoderoso. ctrl + c Recuerdo en qué se hace clic, ctrl + v Lo duplico, todos ganan.
Dan F
2
No soy un experto ni nada, pero creo que probablemente sería mejor probar e.metaKeyo e.ctrlKeyser en truelugar de asignar valores numéricos a las teclas y probarlos.
Sluther
52

Con jquery puede detectar fácilmente copiar, pegar, etc. al vincular la función:

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

Más información aquí: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/

Chris Andersson
fuente
1
Desafortunadamente, este método solo se activará en Firefox si se selecciona texto
Yassir Ennazk
44

Si bien puede ser molesto cuando se usa como una medida contra la piratería, puedo ver que podría haber algunos casos en los que sería legítimo, así que:

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
}

He utilizado en event.ctrlKeylugar de verificar el código de la clave, ya que en la mayoría de los navegadores en Mac OS X Ctrl/ Alteventos "down" y "up" nunca se activan, por lo que la única forma de detectar es usar event.ctrlKeyen el evento, por ejemplo, c después de que la Ctrlclave es presionado. También he sustituido ctrlKeycon metaKeypara Macs.

Limitaciones de este método:

  • Opera no permite deshabilitar eventos de clic derecho

  • Arrastrar y soltar entre las ventanas del navegador no se puede evitar hasta donde yo sé.

  • El elemento de menú edit-> copyen, por ejemplo, Firefox todavía puede permitir copiar / pegar.

  • Tampoco hay garantía de que las personas con diferentes diseños de teclado / configuraciones regionales que copian / peguen / corten sean los mismos códigos de tecla (aunque los diseños a menudo solo siguen el mismo estándar que el inglés), pero la opción general "deshabilitar todas las teclas de control" significa que seleccione todo, etc. también estará deshabilitado, así que creo que es un compromiso que debe hacerse.
crio
fuente
14

Hay otra forma de hacer esto: onpaste , oncopyy oncutlos eventos pueden ser registrados y cancelado de IE, Firefox, Chrome, Safari (con algunos problemas menores), la única gran navegador que no permite la cancelación de estos eventos es Opera.

Como puede ver en mi otra respuesta, interceptar Ctrl+ vy Ctrl+ cviene con muchos efectos secundarios, y aún así no impide que los usuarios peguen usando el Editmenú de Firefox , 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 todavía tiene algunos problemas menores con este método (borra el portapapeles en lugar de cortar / copiar cuando se evita el valor predeterminado), pero ese error parece haberse solucionado en Chrome ahora.

Consulte también: http://www.quirksmode.org/dom/events/cutcopypaste.html y la página de prueba asociada http://www.quirksmode.org/dom/events/tests/cutcopypaste.html para obtener más información.

crio
fuente
9

Demostración en vivo: 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
fuente
8

Solución corta para evitar que el usuario use el menú contextual, copie y corte en jQuery:

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

También puede ser útil desactivar la selección de texto en 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;
}
jendarybak
fuente
4

Si usa la ctrlKeypropiedad, no necesita mantener el estado.

   $(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
fuente
¡Esta es la respuesta correcta! El evento tiene una propiedad ctrlKey = true si se ha presionado una tecla con él. No necesitamos ningún evento extra.
JanBrus
3

Escribí un complemento jQuery, que captura las pulsaciones de teclas. Se puede usar para habilitar la entrada de secuencia de comandos de varios idiomas en formularios html sin el sistema operativo (excepto las fuentes). Son alrededor de 300 líneas de código, tal vez te guste echar un vistazo:

En general, tenga cuidado con este tipo de alteraciones. Escribí el complemento para un cliente porque otras soluciones no estaban disponibles.

miku
fuente
3

Puede usar este código para hacer clic derecho, CTRL+ C, CTRL+ V, CTRL+ Xdetectar y prevenir su acción

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

en lugar de onkeypress, usa onkeydown.

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

No olvide que, si bien puede detectar y bloquear Ctrl+ C/ V, aún puede alterar el valor de un determinado campo.
El mejor ejemplo para esto es la función Inspeccionar elemento de Chrome, que le permite cambiar la propiedad de valor de un campo.

BlueCacti
fuente
0

ya tengo tu problema y lo resolví con el siguiente código ... que solo acepta números

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

puedes detectar Ctrlide.which == 17

Amr Badawy
fuente
-1

Puede escuchar el evento de pulsación de tecla y detener el evento predeterminado (ingresar el texto) si coincide con los códigos de tecla específicos

baloo
fuente
-1

Nota IMPORTANTE

Estuve usando e.keyCodedurante un tiempo y detecté que cuando presiono ctrl+ ., ¡Este atributo devuelve un número incorrecto, 190, mientras que el código ascii de .es 46!

Entonces deberías usar en e.key.toUpperCase().charCodeAt(0)lugar de e.keyCode.

Amir Fo
fuente
-4

Hay algunas formas de prevenirlo.

Sin embargo, el usuario siempre podrá desactivar el javascript o simplemente mirar el código fuente de la página.

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

Editar: como dijo Tim Down, todas estas funciones dependen del navegador.

Gustavo Cardoso
fuente
2
Esto tiene una serie de problemas: primero, no funcionará en los navegadores que no tienen un pasteevento, que incluye todas las versiones de Firefox anteriores a la versión 3. Segundo, window.clipboardDataes solo IE y creo que ahora está deshabilitado por defecto en IE . En tercer lugar, deshabilitar todos los keydowneventos en los que se presiona la tecla Ctrl es excesivo: evita atajos de teclado útiles como Ctrl-A (seleccionar todo) y Ctrl-Z (deshacer). Cuarto, como lo mencionaron otros, esto es algo realmente malo.
Tim Down
Tienes razón en que no funciona en todos los navegadores. Nadie El bloque ctrl es realmente molesto. Fue útil una vez cuando un cliente quería bloquear el campo "Correo electrónico de confirmación y contraseña".
Gustavo Cardoso