Copiar al portapapeles sin Flash

90

Encontré muchas soluciones para copiar al portapapeles, pero todas con flash o para sitios web. Estoy buscando un método para copiar al portapapeles automáticamente, sin flash y para el lado del usuario, es para scripts de usuario y, por supuesto, entre navegadores.

Negro sol
fuente
No he encontrado ninguno, he estado buscando lo mismo. Quería usar Flash, por lo que eliminó esta función antes de la creación.
eugeneK
1
Sin usar FLASH, dudo que pueda hacerlo en varios navegadores. Pero hay una solución concreta disponible que puede ayudarlo a obtener la solución zeroclipboard
Rakesh Sankar
Rakesh: su "solución concreta" se basa en Flash. No funcionará en ningún navegador que utilice.
RobG
1
El método @wizztjh en stackoverflow.com/questions/400212/… es para el lado del sitio no para el lado del usuario @Rakesh zeroclipboard es bueno pero quiero encontrar el método completamente sin Flash
Black_Sun

Respuestas:

31

Sin flash, simplemente no es posible en la mayoría de los navegadores. El portapapeles del usuario es un recurso relevante para la seguridad, ya que podría contener elementos como contraseñas o números de tarjetas de crédito. Por lo tanto, los navegadores no permiten el acceso de Javascript (algunos lo permiten con una advertencia que muestra que el usuario ha confirmado, o con un código Javascript firmado, pero nada de eso es entre navegadores).

Michael Borgwardt
fuente
21
Entonces, tal vez las páginas no deberían poder leerse desde el portapapeles, pero ¿por qué no escribir en él? = /
Ajedi32
5
Pero entonces, ¿por qué permitir que suceda a través de un flash oculto que no implica ninguna notificación ni comentarios del usuario?
Eric Grange
3
@EricGrange: Porque a mediados de la década de 1990, alguien en Netscape decidió que, por razones de rendimiento, los complementos del navegador serían binarios nativos y, por lo tanto, podrían hacer prácticamente cualquier cosa. El mundo en línea era un lugar muy simple en ese entonces, y la seguridad no era una gran preocupación.
Michael Borgwardt
4
Si bien esta respuesta fue cierta en 2011, los navegadores han recorrido un largo camino en la lucha para acabar con el flash. Por favor vea mi respuesta a continuación.
Hovis Biddle
25

Había probado la solución flash y tampoco me gustó. Demasiado complejo y demasiado lento. Lo que hice fue crear un área de texto, poner los datos en eso y usar el comportamiento "CTRL + C" del navegador.

La parte de 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);

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

Ahora, ponga lo que quiere copiar en 'PONGA EL TEXTO A COPIAR AQUÍ. PUEDE SER UNA FUNCIÓN '. zona. Funciona bien para mí. Solo tienes que hacer una combinación CTRL + C. El único inconveniente es que se mostrará un área de texto desagradable en su sitio. Si usa style = "display: none", la solución de copia no funcionará.

Julio Saito
fuente
6
Esto parece solo vincular la función de Ctrl + C a una función de javascript y no colocar los datos en el portapapeles del sistema operativo.
Ismael
seguro, esa es la idea. Haga la copia del navegador por usted. Hay una solución similar aquí: knockoutjs.com/examples/clickCounter.html . Cuando haces doble clic, crean un área de texto mediante javascript con el contenido.
Julio Saito
no funcionó para mí en osx, así que agregué e.metaKeyen la comparación de teclado, pero por alguna razón, la acción de copia no se activa. Vea este violín: jsfiddle.net/gableroux/gta67/1
GabLeRoux
2
@GabLeRoux la función de copia en safari solo está habilitada cuando se selecciona texto. Esto funcionó anteriormente, pero una actualización de safari lo ha detenido recientemente. Parece que seleccionar el texto después de que se llama al evento de tecla abajo ya no lo corta en ese navegador. Sin embargo, todavía funciona bien en cromo. Bueno, es posible que tenga que recurrir al uso de flash solo para ese navegador ...
Aran Mulholland
Me gusta esto. Cuando no puede ocultar (por cualquier motivo) un elemento que no necesita ver, siempre puede colocarlo lejos del inicio, como padding-bottom: -1000.
m3nda
3

Mientras espera con impaciencia la compatibilidad de Xbrowser con la API del portapapeles ...


Esto funcionará a la perfección en Chrome, Firefox, Edge, IE

IE solo solicitará al usuario una vez que acceda al Portapapeles.
Safari (5.1 en el momento de escribir este artículo) no es compatible execCommandconcopy/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 los navegadores (excepto Firefox, que solo puede manejar el tipo mime "plain/text"hasta donde he probado) no han implementado la API del Portapapeles . Es decir, tratando de leer el evento del portapapeles en Chrome usando

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

throws: Uncaught TypeError: constructor ilegal

El mejor recurso del increíble lío que está sucediendo entre los navegadores y el Portapapeles se puede ver aquí (caniuse.com) (→ Siga los comentarios en "Notas" ).
MDN dice que el soporte básico es "(SÍ)" para todos los navegadores, lo cual es inexacto porque uno esperaría que al menos la API funcione, en absoluto.

Roko C. Buljan
fuente
1

Puede utilizar un portapapeles local en la página HTML. Esto le permite copiar / cortar / pegar contenido DENTRO de la página HTML, pero no desde / hacia aplicaciones de terceros o entre dos páginas HTML.

Así es como puede escribir una función personalizada para hacer esto (probado en Chrome y Firefox):

Aquí está el FIDDLE que demuestra cómo puede hacer esto.

También pegaré el violín aquí como referencia.


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
fuente
Hola mtBrona. ¿Hay alguna manera de adjuntar un jsfiddle para este? Parece que no se puede activar
neoswf
¿Podemos pasar una cadena aquí en lugar de elemnt?
Uday A. Navapara
Esto solo funciona si estás dentro del mismo window. No es un Portapapeles real disponible para el sistema operativo y otra pestaña del navegador. Además, la selección se puede hacer fácilmente usando select()y que simplementewindow.getSelection()
Roko C. Buljan
0

document.execCommand('copy')harás lo que quieras. Pero no había ejemplos directamente utilizables en este hilo sin cruft, así que aquí 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
fuente
-2

No hay forma de evitarlo, tienes que usar flash. Existe un complemento de JQuery llamado jquery.copy que proporciona copiar y pegar en varios navegadores mediante un archivo flash (swf). Esto es similar a cómo funciona el resaltador de sintaxis en mi blog.

Una vez que haga referencia al archivo jquery.copy.js, todo lo que necesita hacer para enviar datos al portapapeles es ejecutar lo siguiente:

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

Bonito y fácil ;)

Talha Ahmed Khan
fuente
Enlace roto (los archivos ya no se pueden descargar)
SeinopSys