Copie / coloque texto en el portapapeles con FireFox, Safari y Chrome

113

En Internet Explorer puedo usar el objeto clipboardData para acceder al portapapeles. ¿Cómo puedo hacer eso en FireFox, Safari y / o Chrome?

GvS
fuente
Si quieres hacer esto en cromo de la consola, se puede utilizar copy, developer.chrome.com/devtools/docs/commandline-api
wener
2
posible duplicado de ¿Cómo copiar al portapapeles en JavaScript?
bjb568
1
@ bjb568, la pregunta que mencionaste se ingresó más tarde, así que ese es el duplicado
GvS
@GvS No siempre se trata de cuál se publica primero. El otro fue más popular y obtuvo más respuestas. Si lo desea, márquelo para que un moderador pueda combinar las preguntas.
bjb568
Respuesta bien documentada en stackoverflow.com/a/30810322/712334
Josh Habdas

Respuestas:

21

Ahora hay una forma de hacer esto fácilmente en la mayoría de los navegadores modernos usando

document.execCommand('copy');

Esto copiará el texto seleccionado actualmente. Puede seleccionar un área de texto o un campo de entrada usando

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

Para copiar texto de forma invisible, puede generar rápidamente un área de texto, modificar el texto en el cuadro, seleccionarlo, copiarlo y luego eliminar el área de texto. En la mayoría de los casos, este área de texto ni siquiera parpadea en la pantalla.

Por razones de seguridad, los navegadores solo le permitirán copiar si un usuario realiza algún tipo de acción (es decir, hacer clic en un botón). Una forma de hacer esto sería agregar un evento onClick a un botón html que llama a un método que copia el texto.

Un ejemplo completo:

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

pythonHelpRequired
fuente
50

Por razones de seguridad, Firefox no le permite colocar texto en el portapapeles. Sin embargo, existe una solución alternativa disponible con 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;
}

La única desventaja es que esto requiere que Flash esté habilitado.

la fuente está muerta actualmente: http://bravo9.com/journal/copying-text-into-the-clipboard-with-javascript-in-firefox-safari-ie-opera-292559a2-cc6c-4ebf-9724-d23e8bc5ad8a/ ( y también lo es el caché de Google )

ine
fuente
17
Una tercera desventaja es que no funcionará localmente (archivo: //) sin cambiar los permisos en flash. code.google.com/p/zeroclipboard es una biblioteca construida alrededor de este método.
Regis Frey
@ b1naryatr0phy: Cierto en su mayor parte, pero HTML5 todavía no tiene un reemplazo para la funcionalidad del portapapeles que ofrece actualmente Flash (por ejemplo, usando ZeroClipboard).
James M. Greene
3
A partir de 2014, este método ya no funciona en ningún navegador moderno. ZeroClipboard es la única tecnología que actualmente resuelve esto
Cozzamara
En septiembre de 2015, Flash está muriendo relativamente rápido y ZeroClipboard se basa en su uso. Vea mi respuesta a continuación de agosto de 2015 para una solución que no usa Flash.
un codificador
10

Es el verano de 2015, y con tanta confusión en torno a Flash, pensé en agregar una nueva respuesta a esta pregunta que evite su uso por completo.

clipboard.js es una buena utilidad que permite copiar texto o datos html al portapapeles. Es muy fácil de usar, solo incluye el .js y usa algo como esto:

<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 también está en GitHub

un codificador
fuente
1
El primer enlace que proporciona (a npmjs.com) dice que no funciona con IE, pero sí (como de hecho dice en GitHub)
gordon613
9

En 2017 puedes hacer esto (¡diciendo esto porque este hilo tiene casi 9 años!)

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');
}

Y ahora para copiar copyStringToClipboard('Hello World')

Si notó la setDatalínea y se preguntó si puede establecer diferentes tipos de datos, la respuesta es sí.

Chad Scira
fuente
para safari necesitaba ejecutar un .select()en un cuadro de entrada antes de llamar a esto.
Chad Scira
¿Debería eliminar también el detector de eventos?
Chris Walsh
1
@ChrisWalsh Sí, se hace dentro del controlador en el ejemplo de código. La razón es que, de lo contrario, el controlador seguirá estando en la memoria.
Spoike
8

Firefox te permite almacenar datos en el portapapeles, pero debido a implicaciones de seguridad, está deshabilitado de forma predeterminada. Vea cómo habilitarlo en "Otorgar acceso de JavaScript al portapapeles" en la base de conocimientos de Mozilla Firefox.

La solución ofrecida por amdfan es la mejor si tiene muchos usuarios y configurar su navegador no es una opción. Aunque puede probar si el portapapeles está disponible y proporcionar un enlace para cambiar la configuración, si los usuarios son expertos en tecnología. El editor de JavaScript TinyMCE sigue este enfoque.

Troels Thomsen
fuente
5

La función copyIntoClipboard () funciona para Flash 9, pero parece estar rota por el lanzamiento de Flash Player 10. Aquí hay una solución que funciona con el nuevo Flash Player:

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

Es una solución compleja, pero funciona.

Andomar
fuente
6
No está roto. Se eliminó de la API más reciente por razones de seguridad
glicerina
4

Debo decir que ninguna de estas soluciones realmente funciona . Probé la solución del portapapeles de la respuesta aceptada y no funciona con Flash Player 10. También probé ZeroClipboard y estuve muy contento con él por un tiempo.

Actualmente lo estoy usando en mi propio sitio ( http://www.blogtrog.com ), pero he notado errores extraños con él. La forma en que funciona ZeroClipboard es que coloca un objeto flash invisible en la parte superior de un elemento de su página. Descubrí que si mi elemento se mueve (como cuando el usuario cambia el tamaño de la ventana y tengo las cosas alineadas correctamente), el objeto flash ZeroClipboard se sale de control y ya no cubre el objeto. Sospecho que probablemente todavía esté donde estaba originalmente. Tienen un código que se supone que debe detener eso o volver a pegarlo en el elemento, pero no parece funcionar bien.

Entonces ... en la próxima versión de BlogTrog, supongo que seguiré su ejemplo con todos los demás resaltadores de código que he visto en la naturaleza y eliminaré mi botón Copiar al portapapeles. :-(

(Noté que la copia al portapapeles de dp.syntaxhiglighter también está rota).

Dave Haynes
fuente
3
Es triste cuando la funcionalidad tiene que dar un paso atrás en nombre de la seguridad. Realmente desearía que hubiera una solución que fuera segura y que aún permitiera el acceso al portapapeles desde una página web, incluso si el usuario tiene que otorgarle permiso explícito una vez o algo así.
devios1
Eso es lo que hace IE de forma predeterminada
Matthew Lock
3

pregunta demasiado antigua, pero no vi esta respuesta en ningún lado ...

Consulta este enlace:

http://kb.mozillazine.org/Granting_JavaScript_access_to_the_clipboard

como todos dijeron, por razones de seguridad está deshabilitado por defecto. el enlace de arriba muestra las instrucciones de cómo habilitarlo (editando about: config en firefox o el user.js).

Afortunadamente, hay un complemento llamado "AllowClipboardHelper" que facilita las cosas con solo unos pocos clics. sin embargo, aún debe instruir a los visitantes de su sitio web sobre cómo habilitar el acceso en Firefox.

Pablo
fuente
¿No crees que hay algo como esto para Chrome / WebKit?
devios1
3

Utilice el moderno document.execCommand ("copiar") y jQuery. Ver esta respuesta de 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 llamar:

 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 de Studio.201
fuente
2

He usado Clippy de Github para mis necesidades, un simple botón basado en Flash. Funciona bien, si uno no necesita estilo y está satisfecho con insertar lo que se va a pegar en el lado del servidor de antemano.

Dr1Ku
fuente
1

Una ligera mejora de la solución Flash es la detección de flash 10 mediante swfobject:

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

y luego, si aparece como flash 10, intente cargar un objeto Shockwave usando javascript. Shockwave puede leer / escribir en el portapapeles (en todas las versiones) y usar el comando copyToClipboard () en jerga.

Travis
fuente
1

http://www.rodsdot.com/ee/cross_browser_clipboard_copy_with_pop_over_message.asp funciona con Flash 10 y todos los navegadores compatibles con Flash.

Además, ZeroClipboard se ha actualizado para evitar el error mencionado sobre el desplazamiento de página que hace que la película Flash ya no esté en el lugar correcto.

Dado que ese método "Requiere" que el usuario haga clic en un botón para copiar, esto es conveniente para el usuario y no ocurre nada nefasto.

rdivilbiss
fuente
1

intente crear una variable global de memoria almacenando la selección, luego la otra función puede acceder a la variable y hacer un pegado, por ejemplo.

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
fuente
3
podría copiar desde cualquier otro lugar sin considerar solo dentro de la página
Marwan
1

Si es compatible con flash, puede usar https://everyplay.com/assets/clipboard.swf y usar el texto de flashvars para configurar el texto

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

Ese es el que uso para copiar y puede configurarlo como extra si no admite estas opciones que puede usar:

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

Puede usar el texto y la URL de DataFormat para getData y setData.

Y para borrar datos:

Puede utilizar el archivo, HTML, imagen, texto y URL de DataFormat. PD: necesita utilizar window.clipboardData.clearData (DataFormat);

Y para otros que no son compatibles con window.clipboardData y archivos flash swf, también puede usar el botón control + c en su teclado para Windows y para mac su comando + c

Usuario
fuente
1

Utilice document.execCommand('copy'). Apoyado en las últimas versiones de Chrome, Firefox, Edge, y 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
fuente
1

La API del portapapeles está diseñada para reemplazar document.execCommand. Safari todavía está trabajando en el soporte, por lo que debe proporcionar un respaldo hasta que se establezcan las especificaciones y Safari finalice la implementación.

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 razones de seguridad, Permissionspuede ser necesario el portapapeles para leer y escribir desde el portapapeles. Si el fragmento de código no funciona en SO, inténtelo en localhostun dominio de confianza.

Josh Habdas
fuente
1

Partiendo de la excelente respuesta de @David de Studio.201, esto funciona en Safari, FF y Chrome. También garantiza que no se produzcan flashes desde el textareacolocándolo fuera de la pantalla.

// ================================================================================
// 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
fuente