Copiar para a área de transferência sem Flash

90

Encontrei muitas soluções para copiar para a área de transferência, mas todas elas com flash ou para sites. Estou procurando um método para copiar para a área de transferência automaticamente, sem flash e para o lado do usuário, é para scripts de usuário e, claro, cross-browser.

Sol preto
fonte
Não encontrei nenhum, estou procurando a mesma coisa. Queria usar o Flash, portanto, removeu este recurso da criação anterior.
eugeneK de
1
Sem usar o FLASH, duvido que você consiga fazer isso em vários navegadores. Mas existem soluções concretas disponíveis que podem ajudá-lo a obter a solução zeroclipboard
Rakesh Sankar
Rakesh - sua "solução concreta" é baseada em Flash. Não funcionará em nenhum navegador que eu uso.
RobG de
1
O método @wizztjh em stackoverflow.com/questions/400212/… é para o lado do site, não para o lado do usuário @Rakesh zeroclipboard é bom, mas eu quero encontrar o método completamente sem Flash
Black_Sun

Respostas:

31

Sem o flash, isso simplesmente não é possível na maioria dos navegadores. A área de transferência do usuário é um recurso relevante para a segurança, pois pode conter coisas como senhas ou números de cartão de crédito. Assim, os navegadores corretamente não permitem o acesso Javascript a ele (alguns permitem com um aviso mostrado que o usuário confirmou, ou com código Javascript assinado, mas nada disso é cross-browser).

Michael Borgwardt
fonte
21
Portanto, talvez as páginas não devam ser lidas na área de transferência, mas por que não escrever nela? = /
Ajedi32 de
5
Mas então por que permitir que isso aconteça por meio de um flash oculto que não envolve nenhuma notificação e feedback do usuário?
Eric Grange
3
@EricGrange: Porque em meados dos anos 90, alguém na Netscape decidiu que, por motivos de desempenho, os plug-ins do navegador seriam binários nativos e, portanto, capazes de fazer praticamente qualquer coisa. O mundo online era um lugar muito simples naquela época, e a segurança não era uma grande preocupação.
Michael Borgwardt de
4
Embora essa resposta fosse verdadeira em 2011, os navegadores já percorreram um longo caminho na luta para matar o flash. Por favor, veja minha resposta abaixo.
Hovis Biddle
25

Já tinha experimentado a solução flash e também não gostei. Muito complexo e muito lento. O que fiz foi criar uma textarea, colocar os dados nela e usar o comportamento "CTRL + C" do navegador.

A parte jQuery javascript:

// catch the "ctrl" combination keydown
$.ctrl = function(key, callback, args) {
    $(document).keydown(function(e) {
        if(!args) args=[]; // IE barks when args is null
        if(e.keyCode == key && e.ctrlKey) {
            callback.apply(this, args);
            return false;
        }
    });
};

// put your data on the textarea and select all
var performCopy = function() {
    var textArea = $("#textArea1");
    textArea.text('PUT THE TEXT TO COPY HERE. CAN BE A FUNCTION.');
    textArea[0].focus();
    textArea[0].select();
};

// bind CTRL + C
$.ctrl('C'.charCodeAt(0), performCopy);

A parte HTML:
<textarea id="textArea1"></textarea>

Agora, coloque o que você deseja copiar em 'COLOQUE O TEXTO PARA COPIAR AQUI. PODE SER UMA FUNÇÃO. ' área. Funciona bem para mim. Você só precisa fazer uma combinação CTRL + C. A única desvantagem é que você terá uma área de texto feia exibida em seu site. Se você usar o style = "display: none", a solução de cópia não funcionará.

Julio Saito
fonte
6
Isso parece apenas vincular a função Ctrl + C a uma função javascript e não colocar os dados na área de transferência do sistema operacional.
Ishmael
claro, essa é a ideia. Faça a cópia do navegador para você. Há uma solução semelhante aqui: knockoutjs.com/examples/clickCounter.html . Quando você clica duas vezes, eles criam uma área de texto por javascript com o conteúdo.
Julio Saito
não funcionou para mim no osx, então adicionei e.metaKeyna comparação keydown, mas por algum motivo, a ação de cópia não é acionada. Veja este violino: jsfiddle.net/gableroux/gta67/1
GabLeRoux
2
@GabLeRoux a função de cópia no safari só é ativada quando o texto é selecionado. Isso funcionava anteriormente, mas uma atualização do safari recentemente o interrompeu. Parece que selecionar o texto após o evento key down ser chamado simplesmente não o corta mais naquele navegador. Ainda funciona bem no cromo. Bem, talvez tenha que voltar a usar o flash apenas para aquele navegador ...
Aran Mulholland
Como isso. Quando você não pode ocultar (por qualquer motivo) um elemento que você não precisa ver, você sempre pode colocar longe do início, como padding-bottom: -1000.
m3nda
3

Enquanto esperava impacientemente pelo suporte do Xbrowser para a API Clipboard ...


Isso funcionará perfeitamente no Chrome, Firefox, Edge, IE

O IE solicitará ao usuário apenas uma vez para acessar a área de transferência.
Safari (5.1 no momento da escrita) não oferece suporte execCommandparacopy/cut

/**
 * CLIPBOARD
 * https://stackoverflow.com/a/33337109/383904
 */
const clip = e => {
  e.preventDefault();
  
  const cont = e.target.innerHTML;
  const area = document.createElement("textarea");
  
  area.value = e.target.innerHTML; // or use .textContent
  document.body.appendChild(area);
  area.select();
 
  if(document.execCommand('copy')) console.log("Copied to clipboard");
  else prompt("Copy to clipboard:\nSelect, Cmd+C, Enter", cont); // Saf, Other
  
  area.remove();
};


[...document.querySelectorAll(".clip")].forEach(el => 
  el.addEventListener("click", clip)
);
<a class="clip" href="#!">Click an item to copy</a><br>
<a class="clip" href="#!"><i>Lorem</i></a><br>
<a class="clip" href="#!"><b>IPSUM</b></a><br>

<textarea placeholder="Paste here to test"></textarea>

Todos os navegadores (exceto o Firefox, que só consegue lidar com o tipo MIME "plain/text", até onde testei) não implementaram a API Clipboard . Ou seja, tentando ler o evento da área de transferência no Chrome usando

var clipboardEvent = new ClipboardEvent("copy", {
        dataType: "plain/text",
        data: "Text to be sent to clipboard"
});

throws: Uncaught TypeError: Illegal constructor

O melhor recurso da incrível bagunça que está acontecendo entre os navegadores e a área de transferência pode ser visto aqui (caniuse.com) (→ Siga os comentários em "Notas" ).
MDN diz que o suporte básico é "(SIM)" para todos os navegadores, o que é impreciso porque seria de se esperar que pelo menos a API funcionasse.

Roko C. Buljan
fonte
1

Você pode usar uma área de transferência local para a página HTML. Isso permite que você copie / recorte / cole conteúdo DENTRO da página HTML, mas não de / para aplicativos de terceiros ou entre duas páginas HTML.

É assim que você pode escrever uma função personalizada para fazer isso (testado no Chrome e Firefox):

Aqui está o FIDDLE que demonstra como você pode fazer isso.

Também colarei o violino aqui para referência.


HTML

<p id="textToCopy">This is the text to be copied</p>
<input id="inputNode" type="text" placeholder="Copied text will be pasted here" /> <br/>

<a href="#" onclick="cb.copy()">copy</a>
<a href="#" onclick="cb.cut()">cut</a>
<a href="#" onclick="cb.paste()">paste</a>

JS

function Clipboard() {
    /* Here we're hardcoding the range of the copy
    and paste. Change to achieve desire behavior. You can
    get the range for a user selection using
    window.getSelection or document.selection on Opera*/
    this.oRange = document.createRange();
    var textNode = document.getElementById("textToCopy");
    var inputNode = document.getElementById("inputNode");
    this.oRange.setStart(textNode,0);
    this.oRange.setEndAfter(textNode);
    /* --------------------------------- */
}

Clipboard.prototype.copy = function() {
    this.oFragment= this.oRange.cloneContents();
};

Clipboard.prototype.cut = function() {
    this.oFragment = this.oRange.extractContents();
};

Clipboard.prototype.paste = function() {
    var cloneFragment=this.oFragment.cloneNode(true)
    inputNode.value = cloneFragment.textContent;
};

window.cb = new Clipboard();
mrBorna
fonte
Ei mtBrona. Existe uma maneira de você anexar algum jsfiddle para este? Não consigo ativá-lo
neoswf
Podemos passar a string aqui no lugar do elemento
Uday A. Navapara,
Isso funciona apenas se você estiver dentro do mesmo window. Não é uma área de transferência real disponível para o sistema operacional e outra guia do navegador. Além disso, a seleção pode ser feita facilmente usando select()e não simplesmentewindow.getSelection()
Roko C. Buljan
0

document.execCommand('copy')vai fazer o que você quiser. Mas não havia exemplos diretamente utilizáveis ​​neste segmento sem cruft, então aqui está:

var textNode = document.querySelector('p').firstChild
var range = document.createRange()
var sel = window.getSelection()

range.setStart(textNode, 0)
range.setEndAfter(textNode)
sel.removeAllRanges()
sel.addRange(range)
document.execCommand('copy')
odinho - Velmont
fonte
-2

Não tem jeito, você tem que usar o flash. Há um plug-in JQuery chamado jquery.copy que fornece copiar e colar no navegador cruzado usando um arquivo flash (swf). Isso é semelhante a como funciona o realce de sintaxe no meu blog.

Depois de fazer referência ao arquivo jquery.copy.js, tudo o que você precisa fazer para enviar os dados para a área de transferência é executar o seguinte:

$.copy("some text to copy");

Legal e fácil ;)

Talha Ahmed Khan
fonte
Link quebrado (os arquivos não estão mais disponíveis para download)
SeinopSys