Certains sites Web utilisent maintenant un service JavaScript de Tynt qui ajoute du texte au contenu copié.
Si vous copiez du texte à partir d'un site à l'aide de cela, puis collez-le, vous obtenez un lien vers le contenu d'origine au bas du texte.
Tynt suit également cela au fur et à mesure. C'est une astuce bien faite.
Leur script est impressionnant. Plutôt que d’essayer de manipuler le presse-papiers (ce que seules les anciennes versions de IE leur permettent de faire par défaut et qui doit toujours être désactivé), ils manipulent la sélection.
Ainsi, lorsque vous sélectionnez un bloc de texte, le contenu supplémentaire est ajouté en tant que <div>
caché inclus dans votre sélection. Lorsque vous collez le style supplémentaire est ignoré et le lien supplémentaire apparaît.
C'est en fait assez facile à faire avec de simples blocs de texte, mais un cauchemar lorsque vous considérez toutes les sélections possibles avec du HTML complexe dans différents navigateurs.
Je développe une application Web - je ne veux pas que quiconque soit capable de suivre le contenu copié et j'aimerais que les informations supplémentaires contiennent quelque chose de contextuel, plutôt qu'un simple lien. Le service de Tynt n'est pas vraiment approprié dans ce cas.
Est-ce que quelqu'un connaît une bibliothèque JavaScript open source (peut-être un plug-in jQuery ou similaire) offrant des fonctionnalités similaires mais n'exposant pas les données d'application internes?
Il existe deux manières principales d'ajouter des informations supplémentaires au texte Web copié.
L'idée est de surveiller le copy event
, puis d'ajouter un conteneur caché avec nos informations supplémentaires à la dom
et d'étendre la sélection à celui-ci.
Cette méthode est adaptée de cet article by c.bavota. Vérifiez également la version de jitbit pour les cas plus complexes.
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);
L'idée est de regarder le copy event
et de modifier directement les données du presse-papier. Ceci est possible en utilisant la propriété clipboardData
. Notez que cette propriété est disponible dans tous les principaux navigateurs dans read-only
; la méthode setData
est uniquement disponible sur IE.
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);
Ceci est une solution javascript Vanilla d'une solution modifiée ci-dessus mais prend en charge plusieurs navigateurs (méthode multi-navigateurs)
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 version la plus courte pour jQuery que j'ai testée et qui fonctionne est la suivante:
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);
});
En améliorant la réponse, restaurez la sélection après les modifications pour éviter les sélections aléatoires après la copie.
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');
var range = selection.getRangeAt(0); // edited according to @Vokiel's comment
//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);
selection.removeAllRanges();
selection.addRange(range);
}, 100);
}
document.addEventListener('copy', addLink);
Amélioration pour 2018
document.addEventListener('copy', function (e) {
var selection = window.getSelection();
e.clipboardData.setData('text/plain', $('<div/>').html(selection + "").text() + "\n\n" + 'Source: ' + document.location.href);
e.clipboardData.setData('text/html', selection + '<br /><br />Source: <a href="' + document.location.href + '">' + document.title + '</a>');
e.preventDefault();
});
C'est une compilation de 2 réponses ci-dessus + compatibilité avec Microsoft Edge.
J'ai également ajouté une restauration de la sélection d'origine à la fin, comme prévu par défaut dans n'importe quel navigateur.
function addCopyrightInfo() {
//Get the selected text and append the extra info
var selection, selectedNode, html;
if (window.getSelection) {
var selection = window.getSelection();
if (selection.rangeCount) {
selectedNode = selection.getRangeAt(0).startContainer.parentNode;
var container = document.createElement("div");
container.appendChild(selection.getRangeAt(0).cloneContents());
html = container.innerHTML;
}
}
else {
console.debug("The text [selection] not found.")
return;
}
// Save current selection to resore it back later.
var range = selection.getRangeAt(0);
if (!html)
html = '' + selection;
html += "<br/><br/><small><span>Source: </span><a target='_blank' title='" + document.title + "' href='" + document.location.href + "'>" + document.title + "</a></small><br/>";
var 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.
selectedNode.appendChild(newdiv); // *For the Microsoft Edge browser so that the page wouldn't scroll to the bottom.
newdiv.innerHTML = html;
selection.selectAllChildren(newdiv);
window.setTimeout(function () {
selectedNode.removeChild(newdiv);
selection.removeAllRanges();
selection.addRange(range); // Restore original selection.
}, 5); // Timeout is reduced to 10 msc for Microsoft Edge's sake so that it does not blink very noticeably.
}
document.addEventListener('copy', addCopyrightInfo);
Aussi une solution un peu plus courte:
jQuery( document ).ready( function( $ )
{
function addLink()
{
var sel = window.getSelection();
var pagelink = "<br /><br /> Source: <a href='" + document.location.href + "'>" + document.location.href + "</a><br />© text is here";
var div = $( '<div>', {style: {position: 'absolute', left: '-99999px'}, html: sel + pagelink} );
$( 'body' ).append( div );
sel.selectAllChildren( div[0] );
div.remove();
}
document.oncopy = addLink;
} );