¿Cómo puedo copiar el texto dentro de un div al portapapeles? Tengo un div y necesito añadir un enlace que añada el texto al portapapeles. ¿Hay alguna solución para esto?
<p class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<a class="copy-text">copy Text</a>
Después de hacer clic en copiar el texto, y luego presiono Ctrl + V, se debe pegar.
Hay otra forma que no es Flash (aparte de la API del Portapapeles mencionada en la respuesta de jfriend00's). Tienes que seleccionar el texto y luego ejecutar el comando copy
para copiar al portapapeles el texto que esté seleccionado en la página.
Por ejemplo, esta función copiará el contenido del elemento pasado en el portapapeles (actualizado con la sugerencia en los comentarios de PointZeroTwo):
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
}
Así es como funciona:
document.execCommand("copy")
.Puedes ver una demostración rápida aquí:
-- begin snippet: js hide: false -->
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="p1">P1: I am paragraph 1</p>
<p id="p2">P2: I am a second paragraph</p>
<button onclick="copyToClipboard('#p1')">Copy P1</button>
<button onclick="copyToClipboard('#p2')">Copy P2</button>
<br/><br/><input type="text" placeholder="Paste here for test" />
Fin del fragmento;
El principal problema es que no todos los navegadores soportan esta característica por el momento, pero puedes utilizarla en los principales desde:
Actualización 1: Esto se puede lograr también con una solución pura de JavaScript (sin jQuery):
-- begin snippet: js hide: false console: false babel: false -->
function copyToClipboard(elementId) {
// Create a "hidden" input
var aux = document.createElement("input");
// Assign it the value of the specified element
aux.setAttribute("value", document.getElementById(elementId).innerHTML);
// Append it to the body
document.body.appendChild(aux);
// Highlight its content
aux.select();
// Copy the highlighted text
document.execCommand("copy");
// Remove it from the body
document.body.removeChild(aux);
}
<p id="p1">P1: I am paragraph 1</p>
<p id="p2">P2: I am a second paragraph</p>
<button onclick="copyToClipboard('p1')">Copy P1</button>
<button onclick="copyToClipboard('p2')">Copy P2</button>
<br/><br/><input type="text" placeholder="Paste here for test" />
Fin del fragmento;
Observa que ahora pasamos el id sin el #.
Como madzohan informó en los comentarios, hay algún problema extraño con la versión de 64 bits de Google Chrome en algunos casos (ejecutando el archivo localmente). Este problema parece solucionarse con la solución sin jQuery de arriba.
Madzohan probó en Safari y la solución funcionó pero usando document.execCommand('SelectAll')
en lugar de usar .select()
(como se especifica en el chat y en los comentarios de abajo).
Como señala PointZeroTwo en los comentarios, el código podría mejorarse para que devolviera un resultado de éxito/fracaso. Puedes ver una demostración en [este jsFiddle][7].
Como ha señalado un usuario en la versión española de StackOverflow, las soluciones anteriores funcionan perfectamente si se quiere copiar el contenido de un elemento literalmente, pero no funcionan tan bien si se quiere pegar el texto copiado con formato (al copiarse en un `input type="text", el formato se "pierde").
Una solución para eso sería copiar en un div
editable de contenido y luego copiarlo usando el execCommand
de manera similar. Aquí hay un ejemplo - haga clic en el botón de copiar y luego pegar en el cuadro editable de contenido a continuación:
begin snippet: js hide: false console: true babel: false -->
function copy(element_id){
var aux = document.createElement("div");
aux.setAttribute("contentEditable", true);
aux.innerHTML = document.getElementById(element_id).innerHTML;
aux.setAttribute("onfocus", "document.execCommand('selectAll',false,null)");
document.body.appendChild(aux);
aux.focus();
document.execCommand("copy");
document.body.removeChild(aux);
}
#target {
width:400px;
height:100px;
border:1px solid #ccc;
}
<p id="demo"><b>Bold text</b> and <u>underlined text</u>.</p>
<button onclick="copy('demo')">Copy Keeping Format</button>
<div id="target" contentEditable="true"></div>
...fin del fragmento..;
Y en jQuery, sería así:
function copy(selector){
var $temp = $("<div>");
$("body").append($temp);
$temp.attr("contenteditable", true)
.html($(selector).html()).select()
.on("focus", function() { document.execCommand('selectAll',false,null); })
.focus();
document.execCommand("copy");
$temp.remove();
}
#target {
width:400px;
height:100px;
border:1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="demo"><b>Bold text</b> and <u>underlined text</u>.</p>
<button onclick="copy('#demo')">Copy Keeping Format</button>
<div id="target" contentEditable="true"></div>
...fin del fragmento..;
Editado a partir de 2016
A partir de 2016, ahora se puede copiar texto en el portapapeles en la mayoría de los navegadores porque la mayoría de los navegadores tienen la capacidad de copiar programáticamente una selección de texto en el portapapeles utilizando document.execCommand("copy")
que funciona a partir de una selección.
Al igual que con otras acciones en un navegador (como abrir una nueva ventana), la copia al portapapeles sólo se puede hacer a través de una acción específica del usuario (como un clic del ratón). Por ejemplo, no se puede hacer a través de un temporizador.
Aquí'hay un ejemplo de código:
begin snippet: js hide: false -->
document.getElementById("copyButton").addEventListener("click", function() {
copyToClipboard(document.getElementById("copyTarget"));
});
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
input {
width: 400px;
}
<input type="text" id="copyTarget" value="Text to Copy"> <button id="copyButton">Copy</button><br><br>
<input type="text" placeholder="Click here and press Ctrl-V to see clipboard contents">
Fin del fragmento;
Aquí'hay una demostración un poco más avanzada:
Y, también puedes obtener una biblioteca pre-construida que hace esto por ti con clipboard.js.
Parte histórica de la respuesta
Copiar directamente al portapapeles a través de JavaScript no está permitido por ningún navegador moderno por razones de seguridad. La solución más común es utilizar una función de Flash para copiar en el portapapeles que sólo puede ser activada por un clic directo del usuario.
Como ya se ha mencionado, ZeroClipboard es un popular conjunto de código para gestionar el objeto Flash para hacer la copia. Yo lo he utilizado. Si Flash está instalado en el dispositivo de navegación (lo que descarta el móvil o la tableta), funciona.
La siguiente solución más común es simplemente colocar el texto vinculado al portapapeles en un campo de entrada, mover el foco a ese campo y aconsejar al usuario que pulse Ctrl + C para copiar el texto.
Otras discusiones sobre el problema y posibles soluciones se pueden encontrar en estos posts anteriores de Stack Overflow:
https://stackoverflow.com/questions/400212/how-to-copy-to-the-clipboard-in-javascript
https://stackoverflow.com/questions/1539641/how-to-copy-text-to-the-clients-clipboard-using-jquery
Estas preguntas que piden una alternativa moderna al uso de Flash han recibido muchos votos positivos y ninguna respuesta con una solución (probablemente porque no existe ninguna):
Internet Explorer y Firefox solían tener APIs no estándar para acceder al portapapeles, pero sus versiones más modernas han obviado esos métodos (probablemente por razones de seguridad).
Hay un esfuerzo de estándares nacientes para tratar de llegar a una manera "segura" para resolver los problemas más comunes del portapapeles (probablemente requiriendo una acción específica del usuario como la solución de Flash requiere), y parece que puede ser parcialmente implementado en las últimas versiones de Firefox y Chrome, pero no lo he confirmado todavía.
El texto a copiar está en la entrada de texto, como: <input type="text" id="copyText" name="copyText">
y, al hacer clic en el botón anterior el texto debe copiarse al portapapeles, por lo que el botón es como:<button type="submit" id="copy_button" data-clipboard-target='copyText'>Copy</button>
Su script debe ser como:
<script language="JavaScript">
$(document).ready(function() {
var clip = new ZeroClipboard($("#copy_button"), {
moviePath: "ZeroClipboard.swf"
});
});
</script>
Para los archivos CDN
nota: ZeroClipboard.swf
y ZeroClipboard.js
" el archivo debe estar en la misma carpeta que su archivo que utiliza esta funcionalidad es, O usted tiene que incluir como incluimos <script src=""></script>
en nuestras páginas.