Cómo agregar información adicional al texto web copiado

Resuelto Keith asked hace 14 años • 8 respuestas

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?

Keith avatar Jan 08 '10 15:01 Keith
Aceptado

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>
Expandir fragmento


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>
Expandir fragmento


[Publicación anterior: antes de la actualización de 2020]

Hay dos formas principales de agregar información adicional al texto web copiado.

  1. 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);
  1. Manipular el portapapeles

La idea es observar copy eventy modificar directamente los datos del portapapeles. Esto es posible utilizando la clipboardDatapropiedad. Tenga en cuenta que esta propiedad está disponible en todos los navegadores principales en read-only; el setDatamé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);
CronosS avatar Jan 24 '2011 01:01 CronosS

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);
GiorgosK avatar Mar 27 '2018 09:03 GiorgosK

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);
});
user2276146 avatar Jul 08 '2014 11:07 user2276146