Copiar / colocar texto na área de transferência com FireFox, Safari e Chrome

113

No Internet Explorer, posso usar o objeto clipboardData para acessar a área de transferência. Como posso fazer isso no FireFox, Safari e / ou Chrome?

GvS
fonte
Se você quiser fazer isso em cromo console, você pode usar copy, developer.chrome.com/devtools/docs/commandline-api
Wener
1
@ bjb568, a pergunta que você mencionou foi inserida mais tarde, então esta é a duplicata
GvS
@GvS Nem sempre é sobre qual é postado primeiro. O outro foi mais popular e obteve mais respostas. Se desejar, sinalize para que um moderador possa mesclar as perguntas.
bjb568
Resposta bem documentada em stackoverflow.com/a/30810322/712334
Josh Habdas

Respostas:

21

Agora existe uma maneira de fazer isso facilmente na maioria dos navegadores modernos usando

document.execCommand('copy');

Isso irá copiar o texto atualmente selecionado. Você pode selecionar uma textArea ou campo de entrada usando

document.getElementById('myText').select();

Para copiar o texto de forma invisível, você pode gerar rapidamente um textArea, modificar o texto na caixa, selecioná-lo, copiá-lo e, em seguida, excluir o textArea. Na maioria dos casos, esse textArea nem pisca na tela.

Por motivos de segurança, os navegadores só permitirão a cópia se um usuário realizar algum tipo de ação (por exemplo, clicar em um botão). Uma maneira de fazer isso seria adicionar um evento onClick a um botão html que chama um método que copia o texto.

Um exemplo completo:

function copier(){
  document.getElementById('myText').select();
  document.execCommand('copy');
}
<button onclick="copier()">Copy</button>
<textarea id="myText">Copy me PLEASE!!!</textarea>

pythonHelpRequired
fonte
50

Por razões de segurança, o Firefox não permite que você coloque texto na área de transferência. No entanto, existe uma solução alternativa disponível usando o Flash.

function copyIntoClipboard(text) {

    var flashId = 'flashId-HKxmj5';

    /* Replace this with your clipboard.swf location */
    var clipboardSWF = 'http://appengine.bravo9.com/copy-into-clipboard/clipboard.swf';

    if(!document.getElementById(flashId)) {
        var div = document.createElement('div');
        div.id = flashId;
        document.body.appendChild(div);
    }
    document.getElementById(flashId).innerHTML = '';
    var content = '<embed src="' + 
        clipboardSWF +
        '" FlashVars="clipboard=' + encodeURIComponent(text) +
        '" width="0" height="0" type="application/x-shockwave-flash"></embed>';
    document.getElementById(flashId).innerHTML = content;
}

A única desvantagem é que isso requer que o Flash esteja ativado.

a fonte está morta: http://bravo9.com/journal/copying-text-into-the-clipboard-with-javascript-in-firefox-safari-ie-opera-292559a2-cc6c-4ebf-9724-d23e8bc5ad8a/ ( e o cache do Google também )

ine
fonte
17
Uma terceira desvantagem é que não funcionará localmente (arquivo: //) sem alterar as permissões no flash. code.google.com/p/zeroclipboard é uma biblioteca construída em torno desse método.
Regis Frey
@ b1naryatr0phy: Verdadeiro na maior parte, mas o HTML5 ainda não tem um substituto para a funcionalidade de área de transferência oferecida atualmente pelo Flash (por exemplo, usando ZeroClipboard).
James M. Greene
3
A partir de 2014, esse método não funciona mais em nenhum navegador moderno. ZeroClipboard é a única tecnologia que atualmente resolve isso
Cozzamara
Em setembro de 2015, o Flash estava morrendo de forma relativamente rápida e ZeroClipboard é baseado em seu uso. Veja minha resposta abaixo de agosto de 2015 para uma solução que não usa Flash.
um codificador de
10

É verão de 2015, e com tanta turbulência em torno do Flash, pensei em adicionar uma nova resposta a essa pergunta que evite seu uso.

clipboard.js é um bom utilitário que permite a cópia de texto ou dados html para a área de transferência. É muito fácil de usar, basta incluir o .js e usar algo assim:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.js também está no GitHub

um codificador
fonte
1
O primeiro link que você fornece (para npmjs.com) diz que não funciona com o IE, mas funciona (como de fato diz no GitHub)
gordon613
9

Em 2017, você pode fazer isso (dizendo isso porque este tópico tem quase 9 anos!)

function copyStringToClipboard (string) {
    function handler (event){
        event.clipboardData.setData('text/plain', string);
        event.preventDefault();
        document.removeEventListener('copy', handler, true);
    }

    document.addEventListener('copy', handler, true);
    document.execCommand('copy');
}

E agora para copiar copyStringToClipboard('Hello World')

Se você percebeu a setDatalinha e se perguntou se pode definir diferentes tipos de dados, a resposta é sim.

Chad Scira
fonte
para safari, eu precisava executar um .select()em uma caixa de entrada antes de chamar isso.
Chad Scira
Você deve remover o ouvinte de evento também?
Chris Walsh
1
@ChrisWalsh Sim, isso é feito dentro do manipulador no exemplo de código. O motivo é que o manipulador ainda estará na memória de outra forma.
Spoike,
8

O Firefox permite que você armazene dados na área de transferência, mas devido a implicações de segurança, ele é desabilitado por padrão. Veja como habilitá-lo em "Concedendo acesso JavaScript à área de transferência" na base de conhecimento do Mozilla Firefox.

A solução oferecida por amdfan é a melhor se você tiver muitos usuários e configurar o navegador deles não é uma opção. Embora você possa testar se a área de transferência está disponível e fornecer um link para alterar as configurações, se os usuários tiverem experiência em tecnologia. O editor JavaScript TinyMCE segue essa abordagem.

Troels Thomsen
fonte
5

A função copyIntoClipboard () funciona para Flash 9, mas parece estar quebrada com o lançamento do Flash player 10. Esta é uma solução que funciona com o novo flash player:

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/

É uma solução complexa, mas funciona.

Andomar
fonte
6
Não está quebrado. Foi removido da API mais recente por motivos de segurança
Glicerina
4

Devo dizer que nenhuma dessas soluções realmente funciona. Tentei a solução da área de transferência a partir da resposta aceita e ela não funciona com o Flash Player 10. Também experimentei o ZeroClipboard e fiquei muito feliz com ele por algum tempo.

Atualmente estou usando em meu próprio site ( http://www.blogtrog.com ), mas tenho notado bugs estranhos nele. A forma como ZeroClipboard funciona é que ele coloca um objeto flash invisível no topo de um elemento em sua página. Descobri que se meu elemento se move (como quando o usuário redimensiona a janela e eu tenho as coisas alinhadas à direita), o objeto flash ZeroClipboard sai do lugar e não está mais cobrindo o objeto. Eu suspeito que provavelmente ainda está onde estava originalmente. Eles têm um código que supostamente interrompe isso ou o reenvia para o elemento, mas não parece funcionar bem.

Então ... na próxima versão do BlogTrog, acho que vou seguir o exemplo com todos os outros marcadores de código que vi à solta e remover meu botão Copiar para a área de transferência. :-(

(Percebi que a cópia para a área de transferência de dp.syntaxhiglighter também está corrompida agora.)

Dave Haynes
fonte
3
É triste quando a funcionalidade tem que dar um passo atrás em nome da segurança. Eu realmente gostaria que houvesse uma solução que fosse segura e ainda permitisse o acesso à área de transferência de uma página da web, mesmo se o usuário tivesse que conceder permissão explícita uma vez ou algo assim.
devios1
É isso que o IE faz por padrão
Matthew Lock
3

pergunta muito antiga, mas eu não vi essa resposta em lugar nenhum ...

Verifique este link:

http://kb.mozillazine.org/Granting_JavaScript_access_to_the_clipboard

como todo mundo disse, por razões de segurança está desabilitado por padrão. o link acima mostra as instruções de como habilitá-lo (editando about: config no firefox ou o user.js).

Felizmente, existe um plugin chamado "AllowClipboardHelper" que torna as coisas mais fáceis com apenas alguns cliques. no entanto, você ainda precisa instruir os visitantes do seu site sobre como habilitar o acesso no firefox.

Pablo
fonte
Não acho que haja algo assim para Chrome / WebKit?
devios1
3

Use document.execCommand moderno ("copiar") e jQuery. Veja esta resposta stackoverflow

var ClipboardHelper = { // as Object

copyElement: function ($element)
{
   this.copyText($element.text())
},
copyText:function(text) // Linebreaks with \n
{
    var $tempInput =  $("<textarea>");
    $("body").append($tempInput);
    $tempInput.val(text).select();
    document.execCommand("copy");
    $tempInput.remove();
}};

Como ligar:

 ClipboardHelper.copyText('Hello\nWorld');
 ClipboardHelper.copyElement($('body h1').first());

// JQUERY DOCUMENT
;(function ( $, window, document, undefined ) {
  
  var ClipboardHelper = {

    copyElement: function ($element)
    {
       this.copyText($element.text())
    },
    copyText:function(text) // Linebreaks with \n
    {
        var $tempInput =  $("<textarea>");
        $("body").append($tempInput);
      
        //todo prepare Text: remove double whitespaces, trim
        
        $tempInput.val(text).select();
        document.execCommand("copy");
        $tempInput.remove();
    }
};

    $(document).ready(function()
    {
         var $body=$('body');
         
        $body.on('click', '*[data-copy-text-to-clipboard]', function(event) 
        {
            var $btn=$(this);
            var text=$btn.attr('data-copy-text-to-clipboard');
            ClipboardHelper.copyText(text);
        });
      
        $body.on('click', '.js-copy-element-to-clipboard', function(event) 
        {
            ClipboardHelper.copyElement($(this));
        });

    });


})( jQuery, window, document );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<span data-copy-text-to-clipboard=
"Hello
 World">
  Copy Text
</span>
<br><br>
<span class="js-copy-element-to-clipboard">
Hello
World 
Element
</span>

David do Studio.201
fonte
2

Eu usei o Clippy do Github para minhas necessidades, um botão simples baseado em Flash. Funciona muito bem, se alguém não precisar de estilo e estiver satisfeito em inserir o que colar no lado do servidor de antemão.

Dr1Ku
fonte
1

Uma pequena melhoria na solução Flash é detectar o Flash 10 usando swfobject:

http://code.google.com/p/swfobject/

e, se for exibido como flash 10, tente carregar um objeto Shockwave usando javascript. O Shockwave pode ler / escrever na área de transferência (em todas as versões) também usando o comando copyToClipboard () na linguagem.

Travis
fonte
1

http://www.rodsdot.com/ee/cross_browser_clipboard_copy_with_pop_over_message.asp funciona com Flash 10 e todos os navegadores habilitados para Flash.

Além disso, ZeroClipboard foi atualizado para evitar o bug mencionado sobre rolagem de página, fazendo com que o filme Flash não esteja mais no lugar correto.

Uma vez que esse método "requer" que o usuário clique em um botão para copiar, é uma conveniência para o usuário e nada de nefasto está ocorrendo.

rdivilbiss
fonte
1

tente criar uma variável global de memória armazenando a seleção, então a outra função pode acessar a variável e colar, por exemplo ..

var memory = '';//outside the functions but within the script tag.

function moz_stringCopy(DOMEle,firstPos,secondPos) {

var copiedString = DOMEle.value.slice(firstPos, secondPos);
memory = copiedString;

}

function moz_stringPaste(DOMEle, newpos) {

    DOMEle.value = DOMEle.value.slice(0,newpos) + memory + DOMEle.value.slice(newpos);

}
David Barrett
fonte
3
poderia copiar de qualquer outro lugar, sem considerar apenas dentro da página
Marwan
1

Se você tem suporte para flash, pode usar https://everyplay.com/assets/clipboard.swf e usar o texto flashvars para definir o texto

https://everyplay.com/assets/clipboard.swf?text=It%20Works

É aquele que eu uso para copiar e você pode definir como extra se não suportar estas opções que você pode usar:

Para Internet Explorer: window.clipboardData.setData (DataFormat, Text) e window.clipboardData.getData (DataFormat)

Você pode usar o Texto e Url do DataFormat para getData e setData.

E para excluir dados:

Você pode usar o arquivo, HTML, imagem, texto e URL do DataFormat. PS: Você precisa usar window.clipboardData.clearData (DataFormat);

E para outros arquivos que não suportam window.clipboardData e swf flash, você também pode usar o botão control + c do teclado para windows e para mac seu comando + c

Do utilizador
fonte
1

Use document.execCommand('copy'). Compatível com as versões mais recentes Chrome, Firefox, Edge, e Safari.

function copyText(text){
  function selectElementText(element) {
    if (document.selection) {
      var range = document.body.createTextRange();
      range.moveToElementText(element);
      range.select();
    } else if (window.getSelection) {
      var range = document.createRange();
      range.selectNode(element);
      window.getSelection().removeAllRanges();
      window.getSelection().addRange(range);
    }
  }
  var element = document.createElement('DIV');
  element.textContent = text;
  document.body.appendChild(element);
  selectElementText(element);
  document.execCommand('copy');
  element.remove();
}


var txt = document.getElementById('txt');
var btn = document.getElementById('btn');
btn.addEventListener('click', function(){
  copyText(txt.value);
})
<input id="txt" value="Hello World!" />
<button id="btn">Copy To Clipboard</button>

Trevor
fonte
1

A API Clipboard foi projetada para substituir document.execCommand. O Safari ainda está trabalhando no suporte, então você deve fornecer uma alternativa até que as especificações sejam estabelecidas e o Safari conclua a implementação.

const permalink = document.querySelector('[rel="bookmark"]');
const output = document.querySelector('output');
permalink.onclick = evt => {
  evt.preventDefault();
  window.navigator.clipboard.writeText(
    permalink.href
  ).then(() => {
    output.textContent = 'Copied';
  }, () => {
    output.textContent = 'Not copied';
  });
};
<a href="/programming/127040/" rel="bookmark">Permalink</a>
<output></output>

Por razões de segurança, a área de transferência Permissionspode ser necessária para ler e escrever a partir da área de transferência. Se o snippet não funcionar no SO, experimente localhostou em um domínio de outra forma confiável.

Josh Habdas
fonte
1

Com base na excelente resposta de @David do Studio.201, isso funciona no Safari, FF e Chrome. Ele também garante que não ocorra flashing do textareacolocando-o fora da tela.

// ================================================================================
// ClipboardClass
// ================================================================================
var ClipboardClass = (function() {


   function copyText(text) {
    // Create temp element off-screen to hold text.
        var tempElem = $('<textarea style="position: absolute; top: -8888px; left: -8888px">');
        $("body").append(tempElem);

        tempElem.val(text).select();
        document.execCommand("copy");
        tempElem.remove();
   }


    // ============================================================================
   // Class API
   // ============================================================================
    return {
        copyText: copyText
    };
})();
Crashalot
fonte