Como detectar Ctrl + V, Ctrl + C usando JavaScript?

173

Como detectar ctrl+ v, ctrl+ cusando Javascript?

Preciso restringir a colar nas minhas áreas de texto, o usuário final não deve copiar e colar o conteúdo, o usuário deve digitar apenas o texto na área de texto.

Como conseguir isso?

Ramakrishnan
fonte
3
Qual é o propósito disso? Os únicos dois cenários legítimos em que posso pensar são campos de senha (dos quais você não pode copiar de qualquer maneira) e um teste de velocidade de digitação. Tenho certeza de que você pode detectar uma digitação suspeita rápida.
Paul Butcher
9
@Paul Butcher, @Propeng: Existem cenários em que você precisa disso. Exemplo muito simples: um site para aprender idiomas estrangeiros. O efeito de aprendizado é aprimorado, se você digitar as palavras manualmente, em vez de copiar e colar.
Back2dos 25/05
2
Outra situação legítima pode ser onde a entrada dupla é necessária para detectar erros (por exemplo, digite seu e-mail duas vezes, para que saibamos que não houve erro de digitação). Ainda assim, esse usuário pode manter uma lista de endereços de e-mail gerados aleatoriamente (por exemplo, sneakemail) e provavelmente deseja colá-lo para fins de precisão.
Paul Butcher
40
@ Paul Butcher - essa não é uma situação legítima, eu odeio sites que fazem isso e sempre copio / colo meu endereço de e-mail (longo) de uma entrada para a outra. Quebrar copiar / colar é um grande problema de usabilidade. Isso realmente impressiona o usuário, porque é tão fundamental para o seu modelo mental que ele espera que "apenas funcione". É como se você tentasse puxar uma porta e ela se afastasse de você em vez de na sua direção!
EMP
4
Sempre que uma cópia desse tipo não for permitida em uma página, o que faço é colar o texto em outro lugar (uso a barra de URL) e, em seguida, Ctrl + A (selecione o texto colado no URL), arraste e solte o botão campo na navegação, onde a pasta está desativada. Eu acho que isso é algo que não pode ser evitado até hoje.
precisa saber é o seguinte

Respostas:

180

Eu apenas fiz isso por interesse. Concordo que não é a coisa certa a ser feita, mas acho que deve ser a decisão do op ... Também o código pode ser facilmente estendido para adicionar funcionalidade, em vez de removê-la (como uma área de transferência mais avançada ou Ctrl+ sacionar um servidor lado salvar).

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

Também apenas para esclarecer, esse script requer a biblioteca jQuery.

Codepen demo

EDIT: removeu 3 linhas redundantes (envolvendo e.which) graças à sugestão de Tim Down (ver comentários)

EDIT: adicionado suporte para Macs ( cmdchave em vez de ctrl)

jackocnr
fonte
4
Por que os manipuladores keydowne ? Você pode testar a tecla Ctrl no manipulador. Além disso, não há necessidade do bit: funciona em todos os navegadores que funcionam, portanto nunca será usado. Talvez você estivesse pensando em como obter um código de caractere de um evento? Por fim, isso não fará nada com pastas do contexto ou menus de edição, mas suponho que o OP não tenha perguntado diretamente sobre isso. keyupdocument$(".no-copy-paste").keydowne.keyCode || e.whiche.keyCodee.whiche.whichkeypress
Tim Down
@ Tim: Os manipuladores de teclas Ctrl no documento devem ser gerais - pois eles podem não querer que a variável ctrlDown seja vinculada exclusivamente às entradas sem copiar e colar. Talvez seja OTT. Obrigado pela dica e.which - passei meia hora pesquisando os diferentes casos de uso do e.keyCode e e.which com keydown () e keypress (), e que confusão (especialmente no Firefox)!
25410 jackocnr
1
jackocnr: eu recomendo o artigo sobre manipulação de chaves JavaScript de Jan Wolter: unixpapa.com/js/key.html Eu o usei para referência muitas vezes e não encontrei um erro.
Tim Down
3
Cara! Obrigado! Era exatamente isso que eu precisava para permitir que os usuários selecionassem um "elemento" (entrada da agenda) em um aplicativo Web que estou escrevendo, pressione ctrl + c para "copiá-lo" e, em seguida, ctrl + v para "colá-lo", tudo sem realmente interagindo com a poderosa área de transferência abençoada. ctrl + c Lembro-me do que eles clicaram, ctrl + v Eu duplico, todos ganham.
Dan F
2
Não sou especialista nem nada, mas acho que provavelmente seria melhor testar e.metaKeyou e.ctrlKeyser, em truevez de atribuir valores numéricos às chaves e testá-las.
sluther 28/11/12
52

Com o jquery você pode facilmente detectar copiar, colar, etc, vinculando a função:

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

Mais informações aqui: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/

Chris Andersson
fonte
1
Infelizmente, este método só irá disparar no Firefox se o texto for selecionado
Yassir Ennazk
44

Embora possa ser irritante quando usado como uma medida antipirataria, posso ver que pode haver alguns casos em que seria legítimo, então:

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
}

Eu usei, em event.ctrlKeyvez de verificar o código da chave, como na maioria dos navegadores nos eventos Mac OS X Ctrl/ Alt"down" e "up" nunca são acionados, portanto, a única maneira de detectar é usar event.ctrlKeyo evento eg c após a Ctrltecla ser pressionada. pressionado. Eu também substituído ctrlKeycom metaKeypara Macs.

Limitações deste método:

  • O Opera não permite desativar eventos de clique direito

  • Arraste e solte entre as janelas do navegador não podem ser evitadas até onde eu sei.

  • O item de menu edit-> copyno Firefox, por exemplo, ainda pode permitir copiar / colar.

  • Também não há garantia de que, para pessoas com diferentes layouts / localizações de teclado, copiar / colar / recortar sejam os mesmos códigos de tecla (embora os layouts geralmente sigam o mesmo padrão do inglês), mas a opção "desativar todas as teclas de controle" significa que você seleciona tudo, etc. também será desativado, então acho que é um compromisso que precisa ser feito.
crio
fonte
14

Há uma outra maneira de fazer isso: onpaste , oncopye oncutos eventos podem ser registrados e cancelado no IE, Firefox, Chrome, Safari (com alguns pequenos problemas), o único grande navegador que não permite cancelar esses eventos é Opera.

Como você pode ver na minha outra resposta, a interceptação de Ctrl+ ve Ctrl+ cvem com muitos efeitos colaterais, e ainda não impede que os usuários colem usando o Editmenu do 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
}

O Safari ainda tem alguns pequenos problemas com esse método (ele limpa a área de transferência no lugar de recortar / copiar ao impedir o padrão), mas esse bug parece ter sido corrigido no Chrome agora.

Consulte também: http://www.quirksmode.org/dom/events/cutcopypaste.html e a página de teste associada http://www.quirksmode.org/dom/events/tests/cutcopypaste.html para obter mais informações.

crio
fonte
9

Demonstração ao 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
fonte
8

Solução curta para impedir que o usuário use o menu de contexto, copie e recorte no jQuery:

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

Desabilitar também a seleção de texto em CSS pode ser útil:

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

Se você usar a ctrlKeypropriedade, não precisará manter o 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
fonte
Essa é a resposta correta! O evento tem uma propriedade ctrlKey = true se uma tecla foi pressionada com ele. Não precisamos de eventos extras.
JanBrus 29/01
3

Eu escrevi um plugin jQuery, que captura as teclas digitadas. Ele pode ser usado para ativar a entrada de scripts de vários idiomas em formulários html sem o sistema operacional (exceto as fontes). São cerca de 300 linhas de código, talvez você queira dar uma olhada:

Geralmente, tenha cuidado com esse tipo de alteração. Eu escrevi o plugin para um cliente porque outras soluções não estavam disponíveis.

miku
fonte
3

Você pode usar esse código para clicar com o botão direito, CTRL+ C, CTRL+ V, CTRL+ Xdetectar e impedir sua ação

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

em vez de onkeypress, use onkeydown.

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

Não se esqueça de que, embora seja possível detectar e bloquear Ctrl+ C/ V, você ainda pode alterar o valor de um determinado campo.
O melhor exemplo disso é a função Inspect Element do Chrome, que permite alterar a propriedade de valor de um campo.

BlueCacti
fonte
0

eu já tenho seu problema e resolvi-o pelo código a seguir .. que aceita apenas 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;
            }
        });

você pode detectar Ctrlide.which == 17

Amr Badawy
fonte
-1

Você pode ouvir o evento de pressionamento de tecla e interromper o evento padrão (digitando o texto) se ele corresponder aos códigos de tecla específicos

baloo
fonte
-1

Nota importante

Eu estava usando e.keyCodepor um tempo e descobri que quando pressiono ctrl+ ., este atributo retorna um número errado, 190, enquanto o código ascii .é 46!

Então você deve usar em e.key.toUpperCase().charCodeAt(0)vez de e.keyCode.

Amir Fo
fonte
-4

Existem algumas maneiras de evitá-lo.

No entanto, o usuário sempre poderá desativar o javascript ou apenas olhar o código-fonte da página.

Alguns exemplos (requerem 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: Como Tim Down disse, essas funções são todos dependentes do navegador.

Gustavo Cardoso
fonte
2
Isso tem vários problemas: primeiro, ele não funciona em navegadores que não possuem um pasteevento, que inclui todas as versões do Firefox anteriores à versão 3. Segundo, window.clipboardDataé apenas o IE e acredito que agora esteja desativado por padrão no IE . Terceiro, desabilitar todos os keydowneventos em que a tecla Ctrl é pressionada é excessivo: você evita atalhos úteis do teclado, como Ctrl-A (selecionar todos) e Ctrl-Z (desfazer). Quarto, como mencionado por outros, isso é uma coisa muito ruim de se fazer.
Tim Down
Você está certo sobre isso não funcionar em todos os navegadores. Ninguém O bloco ctrl é realmente irritante. Foi útil uma vez quando um cliente desejava bloquear o campo "E-mail e senha de confirmação".
Gustavo Cardoso