Cómo agregar información adicional al texto web copiado
Algunos sitios web utilizan ahora un servicio JavaScript de Tynt que añade texto al contenido copiado.
Si copia texto de un sitio usando esto y luego lo pega, obtendrá un enlace al contenido original en la parte inferior del texto.
Tynt también rastrea esto a medida que sucede. Es un buen truco bien hecho.
Su script para hacer esto es impresionante: en lugar de intentar manipular el portapapeles (que sólo las versiones anteriores de IE les permiten hacer de forma predeterminada y que siempre debe estar desactivado), manipulan la selección real.
Entonces, cuando seleccionas un bloque de texto, el contenido adicional se agrega como oculto <div>
incluido en tu selección. Cuando pega, el estilo adicional se ignora y aparece el enlace adicional.
En realidad, esto es bastante fácil de hacer con simples bloques de texto, pero es una pesadilla si se consideran todas las selecciones posibles en HTML complejo en diferentes navegadores.
Estoy desarrollando una aplicación web. No quiero que nadie pueda rastrear el contenido copiado y me gustaría que la información adicional contenga algo contextual, en lugar de solo un enlace. El servicio de Tynt no es realmente apropiado en este caso.
¿Alguien conoce una biblioteca JavaScript de código abierto (tal vez un complemento jQuery o similar) que proporcione una funcionalidad similar pero que no exponga los datos internos de la aplicación?
Actualización 2022
Solución más compleja que maneja formato de texto enriquecido. La solución 2020 sigue siendo relevante si solo se trata de texto sin formato.
const copyListener = (event) => {
const range = window.getSelection().getRangeAt(0),
rangeContents = range.cloneContents(),
pageLink = `Read more at: ${document.location.href}`,
helper = document.createElement("div");
helper.appendChild(rangeContents);
event.clipboardData.setData("text/plain", `${helper.innerText}\n${pageLink}`);
event.clipboardData.setData("text/html", `${helper.innerHTML}<br>${pageLink}`);
event.preventDefault();
};
document.addEventListener("copy", copyListener);
#richText {
width: 415px;
height: 70px;
border: 1px solid #777;
overflow: scroll;
}
#richText:empty:before {
content: "Paste your copied text here";
color: #888;
}
<h4>Rich text:</h4>
<p>Lorem <u>ipsum</u> dolor sit <b>amet</b>, consectetur <i>adipiscing</i> elit.</p>
<h4>Plain text editor:</h4>
<textarea name="textarea" rows="5" cols="50" placeholder="Paste your copied text here"></textarea>
<h4>Rich text editor:</h4>
<div id="richText" contenteditable="true"></div>
Actualización 2020
Solución que funciona en todos los navegadores recientes .
Tenga en cuenta que esta solución eliminará el formato de texto enriquecido (como negrita y cursiva), incluso cuando lo pegue en un editor de texto enriquecido.
document.addEventListener('copy', (event) => {
const pagelink = `\n\nRead more at: ${document.location.href}`;
event.clipboardData.setData('text/plain', document.getSelection() + pagelink);
event.preventDefault();
});
Lorem ipsum dolor sit <b>amet</b>, consectetur <i>adipiscing</i> elit.<br/>
<textarea name="textarea" rows="7" cols="50" placeholder="paste your copied text here"></textarea>
[Publicación anterior: antes de la actualización de 2020]
Hay dos formas principales de agregar información adicional al texto web copiado.
- Manipular la selección
La idea es buscar el copy event
, luego agregar un contenedor oculto con nuestra información adicional al dom
, y extenderle la selección.
Este método es una adaptación de este artículo de c.bavota . Consulte también la versión de jitbit para casos más complejos.
- Compatibilidad del navegador : Todos los principales navegadores, IE > 8.
- Demostración : demostración de jsFiddle .
- Código javascript :
function addLink() {
//Get the selected text and append the extra info
var selection = window.getSelection(),
pagelink = '<br /><br /> Read more at: ' + document.location.href,
copytext = selection + pagelink,
newdiv = document.createElement('div');
//hide the newly created container
newdiv.style.position = 'absolute';
newdiv.style.left = '-99999px';
//insert the container, fill it with the extended text, and define the new selection
document.body.appendChild(newdiv);
newdiv.innerHTML = copytext;
selection.selectAllChildren(newdiv);
window.setTimeout(function () {
document.body.removeChild(newdiv);
}, 100);
}
document.addEventListener('copy', addLink);
- Manipular el portapapeles
La idea es observar copy event
y modificar directamente los datos del portapapeles. Esto es posible utilizando la clipboardData
propiedad. Tenga en cuenta que esta propiedad está disponible en todos los navegadores principales en read-only
; el setData
método sólo está disponible en IE.
- Compatibilidad del navegador : IE > 4.
- Demostración : demostración de jsFiddle .
- Código javascript :
function addLink(event) {
event.preventDefault();
var pagelink = '\n\n Read more at: ' + document.location.href,
copytext = window.getSelection() + pagelink;
if (window.clipboardData) {
window.clipboardData.setData('Text', copytext);
}
}
document.addEventListener('copy', addLink);
Esta es una solución básica de JavaScript de una solución modificada anterior, pero admite más navegadores (método entre navegadores)
function addLink(e) {
e.preventDefault();
var pagelink = '\nRead more: ' + document.location.href,
copytext = window.getSelection() + pagelink;
clipdata = e.clipboardData || window.clipboardData;
if (clipdata) {
clipdata.setData('Text', copytext);
}
}
document.addEventListener('copy', addLink);
La versión más corta de jQuery que probé y está funcionando es:
jQuery(document).on('copy', function(e)
{
var sel = window.getSelection();
var copyFooter =
"<br /><br /> Source: <a href='" + document.location.href + "'>" + document.location.href + "</a><br />© YourSite";
var copyHolder = $('<div>', {html: sel+copyFooter, style: {position: 'absolute', left: '-99999px'}});
$('body').append(copyHolder);
sel.selectAllChildren( copyHolder[0] );
window.setTimeout(function() {
copyHolder.remove();
},0);
});