¿Cómo copio al portapapeles en JavaScript?

3322

¿Cuál es la mejor manera de copiar texto al portapapeles? (multi-navegador)

Yo he tratado:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

pero en Internet Explorer da un error de sintaxis. En Firefox, dice unsafeWindow is not defined.

Un buen truco sin flash: ¿cómo accede Trello al portapapeles del usuario?

Santiago Corredoira
fuente
Solo por curiosidad, ¿qué es lo que quieres copiar en el portapapeles que el usuario no puede hacer por sí mismo?
scunliffe
233
Nada especial. Pueden hacerlo solos, pero quiero ofrecer también la posibilidad de hacer clic en un botón sin tener que preocuparme de seleccionar la parte correcta del texto.
Santiago Corredoira
44
Esta larga publicación de blog contiene muchas maneras de hacer esto: Acceder al Portapapeles del sistema con JavaScript: ¿un Santo Grial?
Aaron Digulla
Le está dando una excepción indefinida al navegador en IE, así como en FF
Jagadeesh
1
Si podemos poner texto en el portapapeles del usuario, podemos arruinar su portapapeles.
Frank Fang

Respuestas:

2249

Visión general

Hay tres API principales del navegador para copiar en el portapapeles:

  1. API del portapapeles asíncrono [navigator.clipboard.writeText]
    • Parte centrada en texto disponible en Chrome 66 (marzo de 2018)
    • El acceso es asíncrono y usa Promesas de JavaScript , puede escribirse para que las indicaciones del usuario de seguridad (si se muestran) no interrumpan el JavaScript en la página.
    • El texto se puede copiar al portapapeles directamente desde una variable.
    • Solo se admite en páginas publicadas a través de HTTPS.
    • En Chrome 66 páginas en pestañas activas pueden escribir en el portapapeles sin un aviso de permisos.
  2. document.execCommand('copy')
    • La mayoría de los navegadores admiten esto a partir de ~ abril de 2015 (consulte la Ayuda del navegador a continuación).
    • El acceso es sincrónico, es decir, detiene JavaScript en la página hasta que se completa, incluida la visualización y la interacción del usuario con cualquier mensaje de seguridad.
    • El texto se lee del DOM y se coloca en el portapapeles.
    • Durante las pruebas ~ abril de 2015, solo se observó que Internet Explorer mostraba solicitudes de permisos mientras escribía en el portapapeles.
  3. Anular el evento de copia
    • Consulte la documentación de la API del Portapapeles sobre Anulación del evento de copia .
    • Le permite modificar lo que aparece en el portapapeles desde cualquier evento de copia, puede incluir otros formatos de datos que no sean texto sin formato.
    • No se cubre aquí, ya que no responde directamente a la pregunta.

Notas generales de desarrollo

No espere que los comandos relacionados con el portapapeles funcionen mientras está probando el código en la consola. En general, se requiere que la página esté activa (API del portapapeles asíncrono) o requiere la interacción del usuario (por ejemplo, un clic del usuario) para permitir que ( document.execCommand('copy')) acceda al portapapeles. Consulte a continuación para obtener más detalles.

IMPORTANTE (indicado aquí 2020/02/20)

Tenga en cuenta que, dado que esta publicación se escribió originalmente en desuso de permisos en IFRAME de origen cruzado y otros "sandboxing" de IFRAME, se evita que los demos integrados "Ejecutar fragmento de código" y "ejemplo codepen.io" funcionen en algunos navegadores (incluidos Chrome y Microsoft Edge )

Para desarrollar, cree su propia página web, sirva esa página a través de la conexión HTTPS para probar y desarrollar.

Aquí hay una página de prueba / demostración que demuestra el funcionamiento del código: https://deanmarktaylor.github.io/clipboard-test/

Async + Fallback

Debido al nivel de soporte del navegador para la nueva API Async Clipboard, es probable que desee recurrir al document.execCommand('copy')método para obtener una buena cobertura del navegador.

Aquí hay un ejemplo simple (puede que no funcione incrustado en este sitio, lea la nota "importante" arriba):

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  
  // Avoid scrolling to bottom
  textArea.style.top = "0";
  textArea.style.left = "0";
  textArea.style.position = "fixed";

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Fallback: Copying text command was ' + msg);
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
  }

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

(el ejemplo de codepen.io puede no funcionar, lea la nota "importante" anterior) Tenga en cuenta que este fragmento no funciona bien en la vista previa incrustada de Stack Overflow. Puede probarlo aquí: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011

API del portapapeles asíncrono

Tenga en cuenta que existe la posibilidad de "solicitar permiso" y probar el acceso al portapapeles a través de la API de permisos en Chrome 66.

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand ('copia')

El resto de esta publicación trata los matices y detalles de la document.execCommand('copy')API.

Soporte de navegador

El document.execCommand('copy')soporte de JavaScript ha crecido, consulte los enlaces a continuación para obtener actualizaciones del navegador:

Ejemplo simple

(puede no funcionar integrado en este sitio, lea la nota "importante" arriba)

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

Ejemplo complejo: copiar al portapapeles sin mostrar la entrada

El ejemplo anterior simple funciona muy bien si hay una textareao inputelemento visible en la pantalla.

En algunos casos, es posible que desee copiar texto en el portapapeles sin mostrar un elemento input/ textarea. Este es un ejemplo de una forma de evitar esto (básicamente insertar elemento, copiar al portapapeles, eliminar elemento):

Probado con Google Chrome 44, Firefox 42.0a1 e Internet Explorer 11.0.8600.17814.

(puede no funcionar integrado en este sitio, lea la nota "importante" arriba)

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  document.body.removeChild(textArea);
}


var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

Notas adicionales

Solo funciona si el usuario toma una acción

Todas las document.execCommand('copy')llamadas deben realizarse como resultado directo de una acción del usuario, por ejemplo, haga clic en el controlador de eventos. Esta es una medida para evitar jugar con el portapapeles del usuario cuando no lo esperan.

Vea la publicación de Google Developers aquí para obtener más información.

API del portapapeles

Tenga en cuenta que la especificación del borrador de la API del Portapapeles se puede encontrar aquí: https://w3c.github.io/clipboard-apis/

¿Es compatible?

  • document.queryCommandSupported('copy')debería regresar truesi el comando "es compatible con el navegador".
  • y document.queryCommandEnabled('copy')regresar truesi document.execCommand('copy')tendrá éxito si se llama ahora. Verificación para asegurarse de que se llamó al comando desde un hilo iniciado por el usuario y se cumplen otros requisitos.

Sin embargo, como un ejemplo de los problemas de compatibilidad del navegador, Google Chrome desde abril a ~ ~ de octubre de de 2015 devueltos truede document.queryCommandSupported('copy')si el comando se llama desde un hilo iniciado por el usuario.

Observe los detalles de compatibilidad a continuación.

Detalle de compatibilidad del navegador

Si bien una simple llamada a document.execCommand('copy')encapsulado en un try/ catchbloque llamado como resultado de un clic del usuario obtendrá la mayor compatibilidad, el uso tiene algunas condiciones:

Cualquier llamada a document.execCommand, document.queryCommandSupportedo document.queryCommandEnableddebe estar envuelto en un try/ catchbloque.

Las diferentes implementaciones y versiones de navegador lanzan diferentes tipos de excepciones cuando se llama en lugar de regresar false.

Las diferentes implementaciones de navegador todavía están en proceso de cambio y la API del Portapapeles todavía está en borrador, así que recuerde hacer sus pruebas.

Dean Taylor
fuente
41
¿Cómo copiar directamente de una variable de datos .ie var str = "word";:?
jscripter
10
@BubuDaba Cree un ficticio oculto <textarea>con JS, añádalo document.body, establezca su valor en la variable y úselo a ritmo copyTextarea, luego elimínelo inmediatamente después de copiar el contenido.
SeinopSys
3
¿Hay algo para Safari o algún indicador de que se implementará en Safari?
www139
3
La única versión que encontré que funciona en todos los navegadores. Al usar esto en Boostrap Modal encontré que tenía que agregar el área de texto al modal. ¡Daría un +1000 si pudiera por tu solución! ¡GRACIAS!
Patrick
3
@AyaSalama, el punto clave es que la acción "copiar" no puede tener lugar a menos que parezca que el usuario está realizando la acción en el navegador. El usuario no podrá realizar la acción si el elemento está diseñado con "display: none", ya que no podrá verlo ni interactuar con él.
Dean Taylor
1257

La copia automática al portapapeles puede ser peligrosa, por lo tanto, la mayoría de los navegadores (excepto IE) lo hacen muy difícil. Personalmente, utilizo el siguiente truco simple:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

Al usuario se le presenta el cuadro de aviso, donde el texto a copiar ya está seleccionado. Ahora es suficiente presionar Ctrl+ Cy Enter(para cerrar el cuadro) - ¡y listo!

Ahora la operación de copia del portapapeles es SEGURA, porque el usuario lo hace manualmente (pero de una manera bastante directa). Por supuesto, funciona en todos los navegadores.

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>

Jarek Milewski
fuente
9191
Inteligente, pero esto solo admite una sola línea.
Aram Kocharyan
61
Es trivial cambiar la función de "solicitud" a un modo personalizado, la clave del truco es utilizar un campo de contenido editable y preseleccionar el texto, y que no rompa la interfaz de usuario del navegador al hacer que el usuario tome el acción ellos mismos. A ++
Jon z
110
todavía no usa javascript para copiar al portapapeles ^ _ ^
RozzA
23
Si el texto es más de 2000 caracteres será truncado, pero para muestras de texto más pequeños que funciona muy bien
RasTheDestroyer
445
Es extraño que esto obtenga 457 votos a favor mientras no responde la pregunta: ¡copie al portapapeles en Javascript !
stevenvh
300

El siguiente enfoque funciona en Chrome, Firefox, Internet Explorer y Edge, y en versiones recientes de Safari (se agregó soporte de copia en la versión 10 que se lanzó en octubre de 2016).

  • Cree un área de texto y establezca su contenido en el texto que desea copiar en el portapapeles.
  • Agregue el área de texto al DOM.
  • Seleccione el texto en el área de texto.
  • Llame a document.execCommand ("copia")
  • Elimina el área de texto del dom.

Nota: no verá el área de texto, ya que se agrega y elimina dentro de la misma invocación síncrona del código Javascript.

Algunas cosas a tener en cuenta si está implementando esto usted mismo:

  • Por razones de seguridad, esto solo se puede llamar desde un controlador de eventos como clic (al igual que con la apertura de ventanas).
  • Internet Explorer mostrará un diálogo de permiso la primera vez que se actualice el portapapeles.
  • Internet Explorer y Edge se desplazarán cuando el área de texto esté enfocada.
  • execCommand () puede lanzar en algunos casos.
  • Las nuevas líneas y pestañas pueden tragarse a menos que use un área de texto. (La mayoría de los artículos parecen recomendar el uso de un div)
  • El área de texto estará visible mientras se muestra el cuadro de diálogo de Internet Explorer, o bien debe ocultarlo o utilizar la API de clipboardData específica de Internet Explorer.
  • En Internet Explorer, los administradores del sistema pueden deshabilitar la API del portapapeles.

La siguiente función debe manejar todos los siguientes problemas de la manera más limpia posible. Por favor, deje un comentario si encuentra algún problema o tiene alguna sugerencia para mejorarlo.

// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and Internet Explorer 10+.
// Internet Explorer: The clipboard feature may be disabled by
// an administrator. By default a prompt is shown the first
// time the clipboard is used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text);

    }
    else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in Microsoft Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        }
        catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        }
        finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/

Greg Lowe
fuente
99
Buena respuesta: soporte de navegador cruzado, manejo de errores + limpieza. A partir del nuevo soporte actual para queryCommandSupported, la copia al portapapeles ahora es factible en Javascript y esta debería ser la respuesta aceptada, en lugar de la incómoda 'window.prompt ("Copiar al portapapeles: Ctrl + C, Enter", texto) solución alternativa. window.clipboardData es compatible con IE9, por lo que debe agregar IE9 en la lista de soporte del navegador y creo que tal vez IE8 y anteriores también, pero necesita verificar.
user627283
Si. IE 8/9 debería estar bien. Nuestra aplicación no los admite. Entonces no he probado. IE detiene el soporte en enero, así que no estoy demasiado preocupado. Esperemos que el soporte de Safari llegue pronto. Estoy seguro de que está en su radar.
Greg Lowe
44
@SantiagoCorredoira: En 2016, esta merece ser la respuesta aceptada. Considere reasignar el BGT (gran marca verde).
Lawrence Dol
3
@Noitidart Probé y funciona perfectamente para Firefox 54, Chrome 60 y el navegador de borde, incluso cuando el foco no está en el documento html, el error que está teniendo es probablemente específico de la versión FF 55
Tosin John
2
@Noitidart Todavía funciona perfectamente aquí, centrarse en las herramientas de desarrollo no lo detuvo. Y, por cierto, ¿qué hará un usuario normal de una aplicación web con las herramientas de desarrollador
Tosin John
97

Aquí está mi opinión sobre ese ...

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
 }

@korayem: Tenga en cuenta que el uso del inputcampo html no respetará los saltos de línea \ny aplanará cualquier texto en una sola línea.

Como mencionó @nikksan en los comentarios, el uso textareasolucionará el problema de la siguiente manera:

function copy(text) {
    var input = document.createElement('textarea');
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
}
nikksan
fuente
@nikksan cómo copiar la cadena con \n?
sof-03
2
@ sof-03 usa textarea en lugar de entrada y agrega \r\nun salto de línea
nikksan
1
No funciona en Microsoft Edge 42.17134.1.0 en Win10x64
Honsa Stunna
3
He copiado tu respuesta. Funciona en cromo y eso es todo lo que necesito.
user875234
Esta es la solución más simple que funciona con Firefox v68.0.2 (64 bits).
Arya
88

Si desea una solución realmente simple (se tarda menos de 5 minutos en integrarse) y se ve bien desde el primer momento, entonces Clippy es una buena alternativa a algunas de las soluciones más complejas.

Fue escrito por un cofundador de GitHub. Ejemplo de código de inserción Flash a continuación:

<object
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

Recuerde reemplazar #{text}con el texto que necesita copiar y #{bgcolor}con un color.

Brent Matzelle
fuente
12
Para cualquier persona interesada, verifique que Clippy se use en GitHub al copiar la URL para el repositorio.
Radek
66
Para su información, el uso de Clippy en GitHub ha sido reemplazado por ZeroClipboard.
James M. Greene
219
El OP quería una solución en JavaScript. No flash
MT.
21
@MT, por "javascript", algunas personas quieren decir "en el cliente del navegador", por lo que si bien JS solo puede ser un requisito, muchas de las personas que tienen esta respuesta realmente están buscando JS-u-otro-ampliamente compatible- cliente-tech. Flash no afecta a todas las plataformas, pero para una función de pulido como el soporte del portapapeles, vale la pena agregarlo si mejora la UX sobre un cuadro de diálogo emergente (que ciertamente lo hace).
Dave Dopson
13
Ahora confiar en Flash significa que las cosas no funcionan para un porcentaje de visitantes del sitio que es inaceptable para casi todos los que realizan desarrollo web.
jinglesthula
86

Leer y modificar el portapapeles desde una página web plantea problemas de seguridad y privacidad. Sin embargo, en Internet Explorer, es posible hacerlo. Encontré este fragmento de ejemplo :

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />

Bandi
fuente
77
Usar flash para una simple operación de copia parece excesivo, me alegro de que haya una manera limpia de JS de hacer esto. Y ya que estamos en un entorno corporativo. IE está bien. Gracias Bandi!
Eddie
55
por favor explique qué execCommand(\\’copy\\’);hace, si no copiar al portapapeles para IE? @mrBorna
RozzA
20
¡No lo use, if(!document.all)pero if(!r.execCommand)para que nadie más lo implemente! Document.all es absolutamente irrelevante para esto.
m93a
1
Hombre, esto es lo que me encanta del código simple y limpio, funciona casi para siempre con un mantenimiento menor. Esto lo hizo por mí, funciona de maravilla.
Samuel Ramzan
1
no funciona en el último Chrome, Firefox o MS Edge :(
Jonathan Marzullo
69

Recientemente escribí una publicación técnica en un blog sobre este mismo problema (trabajo en Lucidchart y recientemente realizamos una revisión en nuestro portapapeles).

Copiar texto sin formato al portapapeles es relativamente simple, suponiendo que desee hacerlo durante un evento de copia del sistema (el usuario presiona CtrlCo usa el menú del navegador).

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

Poner texto en el portapapeles no durante un evento de copia del sistema es mucho más difícil. Parece que algunas de estas otras respuestas hacen referencia a formas de hacerlo a través de Flash, que es la única forma de hacerlo entre navegadores (hasta donde yo entiendo).

Aparte de eso, hay algunas opciones navegador por navegador.

Esto es lo más simple en IE, donde puede acceder al objeto clipboardData en cualquier momento desde JavaScript a través de:

window.clipboardData

(Sin embargo, cuando intente hacer esto fuera de un evento de cortar, copiar o pegar del sistema, IE solicitará al usuario que otorgue el permiso del portapapeles de la aplicación web).

En Chrome, puede crear una extensión de Chrome que le otorgará permisos de portapapeles (esto es lo que hacemos para Lucidchart). Luego, para los usuarios con su extensión instalada, solo tendrá que activar el evento del sistema usted mismo:

document.execCommand('copy');

Parece que Firefox tiene algunas opciones que permiten a los usuarios otorgar permisos a ciertos sitios para acceder al portapapeles, pero no he probado ninguno de estos personalmente.

Richard Shurtz
fuente
2
No se menciona en la publicación del blog (espero actualizarlo en el futuro cercano), es la capacidad de activar cortar y copiar usando execCommand. Esto es compatible con IE10 +, Chrome 43+ y Opera29 +. Lee sobre esto aquí. updates.html5rocks.com/2015/04/cut-and-copy-commands
Richard Shurtz
Un problema con esto es que secuestra otros eventos de copia normales.
Brock Adams
¡NÓTESE BIEN! Este buscador olfatear es MALO. Presentan olfateo. Estás dificultando la actualización de IE.
odinho - Velmont
51

clipboard.js es una pequeña utilidad que no es Flash y que permite copiar texto o datos HTML en el portapapeles. Es muy fácil de usar, solo incluya el .js y use 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 .

Nota: Esto ha quedado en desuso ahora. Migra a aquí .

un codificador
fuente
Angular.io utiliza esta biblioteca para su Tour of Hero y su respaldo en modo elegante para el navegador que no admite execCommand mostrando un texto preseleccionado que el usuario solo tiene que copiar.
John-Philip
1
Parece que clipboard.js ha sido reemplazado o bifurcado, pero parece vivir y se mantiene activamente en npmjs.com/package/clipboard
Joao
35

ZeroClipboard es la mejor solución de navegador cruzado que he encontrado:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

Si necesita soporte sin flash para iOS, simplemente agregue un respaldo:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard

Justin
fuente
25
navegador cruzado con Flash? no funciona en iOS y Android 4.4
Raptor
1
Ver respuesta actualizada. Esto permite menos pasos para los usuarios de flash y una alternativa para todos los demás.
Justin
8
Tiene mil millones de líneas de código. Es absolutamente ridículo. mejor no hacerlo que incluir un monstruo así en un proyecto
vsync
2
Hay una versión simple gist.github.com/JamesMGreene/8698897 que es 20K que no tiene todas las campanas y silbatos en la versión 74k. Tampoco es muy grande. Supongo que la mayoría de los usuarios están de acuerdo con los milisegundos adicionales que tomará un archivo de 74k o 20k que se descargará, por lo que copiar / pegar es un clic en lugar de dos.
Justin
@Justin No puedo hacer que funcione localmente, incluso si copio y pego los ejemplos (hago cambios mínimos, por ejemplo, el valor de las srcetiquetas de script). Siento que su documentación es bonita pero ineficiente.
Gui Imamura
29

En 2018, así es como puedes hacerlo:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  }
  catch (err) {
    console.error('Failed to copy: ', err);
  }
}

Se usa en mi código Angular 6+ así:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

Si paso una cadena, la copia. Si nada, copia la URL de la página.

También se puede hacer más gimnasia para las cosas del portapapeles. Ver más información aquí:

Desbloqueo del acceso al portapapeles

KhoPhi
fuente
te has vinculado a localhost
Joe Warner
2
Tenga en cuenta que esto no funciona en Safari (versión 11.1.2)
arjun27
1
@ arjun27 Bueno, ojalá algún día Apple se ponga al día. Aunque este caniuse.com/#feat=clipboard muestra la versión anterior que mencionaste como parcialmente compatible.
KhoPhi
2
Estoy obteniendo para ambas funciones readText, writeText una promesa en estado rechazado
ramin
3
De acuerdo con el enlace proporcionado, "navigator.clipboard solo es compatible con páginas servidas a través de HTTPS"
TimH - Codidact
26

De uno de los proyectos en los que he estado trabajando, un complemento jQuery de copiar al portapapeles que utiliza el Portapapeles cero biblioteca .

Es más fácil de usar que el complemento nativo Zero Clipboard si eres un gran usuario de jQuery.

SteamDev
fuente
66
92kb no es tan grande realmente, funciona rápido y puedes usarlo en text()lugar de innerHTML()si lo deseas ..
RozzA
17
@John: innerHTMLha sido compatible con varios navegadores desde hace mucho tiempo. Solo porque a Microsoft se le ocurrió originalmente la idea, no lo hace poco confiable o propietario. Ahora también se está agregando finalmente a la especificación oficial (después de que todos los principales proveedores de navegadores ya le hayan agregado soporte ... suspiro ).
James M. Greene
19
@John Te quejas de que jQuery no es JavaScripty lo suficiente en una respuesta que usa Flash;)
Max Nanasy
44
innerHTML es mejor que las alternativas en la mayoría de los casos. ¡Bájate de tu caballo! Es más rápido, más eficiente y no requiere volver a procesar la página.
Orbitando Eden
44
@RozzA 92KBes realmente grande. Hasta que LTE madure, GPRS es el estándar de datos móviles de WW , y comienza en 1 KB/s. Haz los cálculos tú mismo.
Tino
23

Dado que Chrome 42+ y Firefox 41+ ahora son compatibles con comando document.execCommand ('copy') . Así que he creado un par de funciones para una capacidad multi-navegador de Copiar en el portapapeles utilizando una combinación de vieja respuesta de Tim hacia abajo y la respuesta de Google para desarrolladores :

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } 
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
    but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
    versions of Chrome feature detection does not work!
    See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>

Jeff Baker
fuente
¡Gracias por resumir esto! Tiene algunos pequeños errores en su código: definió la variable "rango" dos veces (var range = document.createRange ()).
Christian Engel
1
Tienes razón @ChristianEngel. He quitado el segundo. No sé cómo llegó allí.
Jeff Baker, el
23

Lo uso con mucho éxito ( sin jQuery o cualquier otro marco).

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } 
    else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
}

Advertencia

Las pestañas se convierten en espacios (al menos en Chrome).

Severo
fuente
Faltan espacios en este enfoque
Bikram
1
Cromo. las pestañas se convierten en un espacio
Bikram
22

Encontré la siguiente solución:

En el controlador de tecla abajo crea la etiqueta "pre". Configuramos el contenido para copiarlo en esta etiqueta, luego hacemos una selección en esta etiqueta y regresamos verdadero en el controlador. Esto llama al controlador estándar de Chrome y copia el texto seleccionado.

Y si lo necesita, puede configurar el tiempo de espera para la función de restaurar la selección anterior. Mi implementación en Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

Uso:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

Al pegar, crea textarea y funciona de la misma manera.

PS puede ser esta solución se puede utilizar para crear una solución completamente entre navegadores sin flash. Funciona en FF y Chrome.

Enyby
fuente
2
¿Alguien ha intentado eso? Suena como una cosa ingeniosa, en caso de que realmente funcione en una variedad de navegadores.
Michael
1
jsfiddle.net/H2FHC Demo: fiddle.jshell.net/H2FHC/show Por favor, ábralo y presione Ctrl + V o Ctrl + C. En FF 19.0 se bifurca perfectamente. En Chrome 25.0.1364.97 m también. Opera 12.14 - OK. Safari 5.1.7 para Windows - OK. IE - FALLO.
Enyby
Para IE necesita ejecutar foco en elemento dentro de la página. Ver fiddle.jshell.net/H2FHC/3/show y fiddle.jshell.net/H2FHC/3 Trabajado en IE 9/10. IE 6/7 necesita que el proceso cree la selección de otra manera porque no se admite document.createRange.
Enyby
21

Los otros métodos copiarán texto plano en el portapapeles. Para copiar HTML (es decir, puede pegar resultados en un editor WSIWYG), puede hacer lo siguiente en IE SOLAMENTE . Esto es fundamentalmente diferente de los otros métodos, ya que el navegador realmente selecciona visiblemente el contenido.

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   
Chase Seibert
fuente
vea una solución HTML más completa aquí stackoverflow.com/questions/34191780/…
kofifus
21

He reunido lo que creo que es el mejor.

  • Utiliza cssText para evitar excepciones en Internet Explorer en lugar de estilo directamente.
  • Restaura la selección si hubo una
  • Establece solo lectura para que el teclado no aparezca en dispositivos móviles
  • Tiene una solución alternativa para iOS para que realmente funcione, ya que normalmente bloquea execCommand.

Aquí está:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // /programming/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    }
    else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    }
    catch (err) {
      console.error(err);
      return false;
    }
  };
})();

Uso: copyToClipboard('some text')

Dominic
fuente
13

A partir de Flash 10, solo puede copiar al portapapeles si la acción se origina en la interacción del usuario con un objeto Flash. ( Lea la sección relacionada del anuncio de Adobe Flash 10 )

La solución es colocar un objeto flash sobre el botón Copiar, o cualquier elemento que inicie la copia. Zero Clipboard es actualmente la mejor biblioteca con esta implementación. Los desarrolladores de Flash con experiencia pueden querer crear su propia biblioteca.

matthuhiggins
fuente
12

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>

Samuel Tees
fuente
La mejor respuesta: D, puedes mejorarlo con algo como esto: #t {position: absolute; izquierda: 0; índice z: -900; ancho: 0px; altura: 0px; borde: ninguno; } ¡Entonces estará completamente oculto! Pero realmente gracias hermano!
Federico Navarrete
#t {redimensionar: ninguno;}
SmartManoj
Una explicación estaría en orden.
Peter Mortensen
12

Encontré la siguiente solución:

Tengo el texto en una entrada oculta. Como setSelectionRangeno funciona en entradas ocultas, cambié temporalmente el tipo de texto, copié el texto y luego lo oculté nuevamente. Si desea copiar el texto de un elemento, puede pasarlo a la función y guardar su contenido en la variable de destino.

jQuery('#copy').on('click', function () {
    copyToClipboard();
});

function copyToClipboard() {
    var target = jQuery('#hidden_text');

    // Make it visible, so can be focused
    target.attr('type', 'text');
    target.focus();
    // Select all the text
    target[0].setSelectionRange(0, target.val().length);

    // Copy the selection
    var succeed;
    try {
        succeed = document.execCommand("copy");
    }
    catch (e) {
        succeed = false;
    }

    // Hide input again
    target.attr('type', 'hidden');

    return succeed;
}
Vassilis Pallas
fuente
11

Copie el texto de la entrada HTML al portapapeles:

 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");

   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">

 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>

Nota: El document.execCommand()método no es compatible con Internet Explorer 9 y versiones anteriores.

Fuente : W3Schools - Copiar texto al portapapeles

Alexandru Sirbu
fuente
11

Ya hay muchas respuestas, sin embargo, me gusta agregar una (jQuery). Funciona muy bien en cualquier navegador, también en dispositivos móviles (es decir, pregunta sobre la seguridad, pero cuando lo acepta, funciona bien).

function appCopyToClipBoard(sText)
{
    var oText = false,
        bResult = false;
    try
    {
        oText = document.createElement("textarea");
        $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
        oText.select();
        document.execCommand("Copy");
        bResult = true;
    }
    catch(e) {
    }

    $(oText).remove();
    return bResult;
}

En su código:

if (!appCopyToClipBoard('Hai there! This is copied to the clipboard.'))
{
    alert('Sorry, copy to clipboard failed.');
}
Codebeat
fuente
9

Esta es una combinación de las otras respuestas.

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

Utiliza jQuery, pero no tiene que hacerlo, por supuesto. Puedes cambiar eso si quieres. Acabo de tener jQuery a mi disposición. También puede agregar un poco de CSS para asegurarse de que la entrada no se muestre. Por ejemplo algo como:

.textToCopyInput{opacity: 0; position: absolute;}

O, por supuesto, también podrías hacer un estilo en línea

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
Bart Burg
fuente
Cómo copiar directamente desde un dato variable .ie: var str = "word"; ?
Mensaje variable no utilizado
Voyager
Mejor usar '<textarea class = "textToCopyInput" /> </textarea>' en caso de que textToCopycontenga\n
Voyager
8

En los navegadores que no sean IE, debe usar un pequeño objeto flash para manipular el portapapeles, p. Ej.

Quog
fuente
Esto está desactualizado ahora ... echa un vistazo a la sugerencia de GvS
Mottie
66
¿La sugerencia de GvS usa una película flash? ¿No es esa la misma idea?
TheEmirOfGroofunkistan
8

Tuve el mismo problema al crear una edición de cuadrícula personalizada (algo así como Excel) y la compatibilidad con Excel. Tuve que soportar seleccionar varias celdas, copiar y pegar.

Solución: cree un área de texto donde inserte datos para que el usuario los copie (para mí cuando el usuario selecciona celdas), establezca el foco en él (por ejemplo, cuando el usuario presiona Ctrl ) y seleccione todo el texto.

Entonces, cuando el usuario presiona Ctrl+C él / ella obtiene las celdas copiadas que él / ella seleccionó. Después de probar, simplemente redimensionar el área de texto a un píxel (no probé si funcionará en la pantalla: ninguno). Funciona bien en todos los navegadores, y es transparente para el usuario.

Pegar: podría hacer lo mismo (difiere en su objetivo): manténgase enfocado en textarea y capture eventos de pegar usando onpaste (en mi proyecto uso textareas en celdas para editar).

No puedo pegar un ejemplo (proyecto comercial), pero entiendes la idea.

xiniu
fuente
7

He usado clipboard.js.

Podemos obtenerlo en npm:

npm install clipboard --save

Y también en Bower

bower install clipboard --save

El uso y los ejemplos están en https://zenorocha.github.io/clipboard.js/ .

CodecPM
fuente
Tenía miedo de que no fuera compatible con el contenido dinámico, pero lo es ;-) Creo que es la mejor solución, AHORA, que la anterior de 2008.
BENARD Patrick
6

Esta es una expansión de la respuesta de @ Chase, con la ventaja de que funcionará para elementos de IMAGEN y TABLA, no solo DIV en IE9.

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
Oliver Bock
fuente
5

Parece que leí mal la pregunta, pero como referencia, puede extraer un rango del DOM (no al portapapeles; compatible con todos los navegadores modernos) y combinarlo con los eventos oncopy y onpaste y onbeforepaste para obtener el comportamiento del portapapeles. Aquí está el código para lograr esto:

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
mrBorna
fuente
1
De hecho, corregí el código. Funciona en todos los navegadores, pero en realidad no se copia al portapapeles. Simplemente extrae (corta), clona (copia) el contenido a través de variables. Parece que había olvidado el uso.
mrBorna
5

Culpa mía. Esto solo funciona en IE.

Aquí hay otra forma de copiar texto:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
dvallejo
fuente
99
Esto no funciona en Chrome (V31) o FireFox (v25) actuales. El error es que window.clipboardData no está definido. En el lado positivo, funciona en IE9. Por lo tanto, siempre y cuando no le interesen los buenos navegadores y quiera bloquear su sitio para que no use los malos, ¡esta es la manera de hacerlo!
Anthony
2
No entiendo por qué tantas respuestas tontas. w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipboard
Martian2049
5

Esto fue lo único que pude trabajar, después de buscar varias maneras en Internet. Este es un tema desordenado. Hay muchas soluciones publicadas en todo el mundo y la mayoría de ellas no funcionan. Esto funcionó para mí:

NOTA: Este código solo funcionará cuando se ejecute como código síncrono directo a algo como un método 'onClick'. Si llama en una respuesta asincrónica a Ajax o de cualquier otra forma asincrónica, no funcionará.

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

Me doy cuenta de que este código mostrará un componente de 1 píxel de ancho visible en la pantalla durante un milisegundo, pero decidí no preocuparme por eso, que es algo que otros pueden abordar si es un problema real.

Peter Mortensen
fuente
5

Para copiar un texto seleccionado ('Texto para copiar') a su portapapeles, cree un Bookmarklet (marcador de navegador que ejecute JavaScript) y ejecútelo (haga clic en él). Creará un área de texto temporal.

Código de GitHub:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
Mau
fuente