Come aggiungere informazioni extra al testo web copiato


103

Alcuni siti Web ora utilizzano un servizio JavaScript di Tynt che aggiunge testo al contenuto copiato.

Se copi del testo da un sito usando questo e poi incolli, ottieni un link al contenuto originale nella parte inferiore del testo.

Tynt tiene traccia anche di questo mentre accade. È un bel trucco ben fatto.

Il loro script per farlo è impressionante: invece di provare a manipolare gli appunti (che solo le versioni precedenti di IE gli consentono di fare di default e che dovrebbero essere sempre disattivati) manipolano la selezione effettiva.

Quindi, quando selezioni un blocco di testo, il contenuto extra viene aggiunto come nascosto <div>incluso nella tua selezione. Quando incolli, lo stile aggiuntivo viene ignorato e viene visualizzato il collegamento aggiuntivo.

Questo è in realtà abbastanza facile da fare con semplici blocchi di testo, ma un incubo se si considerano tutte le selezioni possibili attraverso HTML complessi in diversi browser.

Sto sviluppando un'applicazione web: non voglio che nessuno sia in grado di tenere traccia del contenuto copiato e vorrei che le informazioni extra contenessero qualcosa di contestuale, piuttosto che un semplice collegamento. Il servizio di Tynt non è proprio appropriato in questo caso.

Qualcuno conosce una libreria JavaScript open source (forse un plug-in jQuery o simile) che fornisce funzionalità simili ma che non espone i dati dell'applicazione interna?


1
Dai un'occhiata alla mia risposta su stackoverflow.com/questions/6344588/… . È fatto in modo molto simile a quello che hai proposto
Niklas


48
Per favore, non farlo. PER FAVORE, PER FAVORE, PER FAVORE, non farlo.
Couchand il

5
@couchand perché no? Capisco quanto sia fastidioso sui siti di spam, ma questo è per un'applicazione che può essere utilizzata per citazioni e in cui i dati interni sono sensibili. Ecco perché non volevo usare Tynt.
Keith

4
Sei sicuro di volerlo fare? Come utente, lo odio e porterò questa rabbia nel tuo prodotto: non toccare i miei appunti!
aloisdg si trasferisce su codidact.com il

Risposte:


138

Aggiornamento 2020

Soluzione che funziona su tutti i browser recenti .

document.addEventListener('copy', (event) => {
  const pagelink = `\n\nRead more at: ${document.location.href}`;
  event.clipboardData.setData('text', document.getSelection() + pagelink);
  event.preventDefault();
});
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br/>
<textarea name="textarea" rows="7" cols="50" placeholder="paste your copied text here"></textarea>


[Post più vecchio - prima dell'aggiornamento del 2020]

Esistono due modi principali per aggiungere informazioni extra al testo web copiato.

1. Manipolazione della selezione

L'idea è di cercare copy event, quindi aggiungere un contenitore nascosto con le nostre informazioni extra a domed estendere la selezione ad esso.
Questo metodo è adattato da questo articolo di c.bavota . Controlla anche la versione di jitbit per casi più complessi.

  • Compatibilità del browser : tutti i principali browser, IE> 8.
  • Demo : jsFiddle demo .
  • Codice 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);

2. Manipolazione degli appunti

L'idea è di guardare copy evente modificare direttamente i dati degli appunti. Questo è possibile utilizzando la clipboardDataproprietà. Notare che questa proprietà è disponibile in tutti i principali browser in read-only; il setDatametodo è disponibile solo su IE.

  • Compatibilità del browser : IE> 4.
  • Demo : jsFiddle demo .
  • Codice 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);

1
Saluti! Sfortunatamente abbiamo bisogno che funzioni in IE, ma non è un brutto inizio.
Keith

2
Dovrebbe esserci una soluzione alternativa per i tag "<pre>", una versione più fluida di questo script è qui
Alex

15
Nota che "Manipolazione degli appunti" funziona perfettamente in FireFox, Chrome e Safari se passi window.clipboardDataa event.clipboardData. IE (anche v11) non supporta event.clipboardData jsfiddle.net/m56af0je/8
mems

3
Se utilizzi Google Analytics, ecc., Puoi persino attivare un evento per registrare ciò che gli utenti stanno copiando dal tuo sito. Interessante
geedubb

2
La prima opzione ignora i nuovi caratteri di riga del testo copiato.
Soham

7

Questa è una soluzione javascript vanilla da una soluzione modificata sopra ma supporta più browser (metodo cross browser)

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);

3

La versione più breve per jQuery che ho testato e funziona è:

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);
});

dov'è il codice che copia effettivamente il risultato negli appunti?
vsync

@vsync Credo che questo aggiunga funzionalità appena prima che avvenga la copia (che viene eseguita dal sistema quando l'utente la avvia).
TerranRich

@vsync - come ha detto TerraRich, ho provato a rispondere alla domanda, che riguardava l'aggiunta di informazioni extra nel testo copiato, quindi la soluzione copre solo questa parte.
user2276146

3

Ecco un plugin in jquery per farlo https://github.com/niklasvh/jquery.plugin.clipboard Dal readme del progetto "Questo script modifica il contenuto di una selezione prima che venga chiamato un evento di copia, risultando nella selezione copiata essere diverso da ciò che l'utente ha selezionato.

Ciò consente di aggiungere / anteporre contenuto alla selezione, come informazioni sul copyright o altro contenuto.

Rilasciato con licenza MIT "


1
Sembra molto promettente. Utilizza stili in linea che non consentiamo con il nostro CSP, ma potrebbe essere adattato. Saluti!
Keith

3

Migliorando la risposta, ripristina la selezione dopo le alterazioni per evitare selezioni casuali dopo la copia.

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);

@TsukimotoMitsumasa Dovrebbe essercivar range = selection.getRangeAt(0);
Vokiel

Il ripristino della selezione del testo è una buona idea, altrimenti interrompe il comportamento predefinito del browser.
Sergey

2

Miglioramento per il 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();
});

1
Quando si copia-incolla si perde la formattazione ( <a> , <img> , <b> e altri tag). È meglio ottenere il codice HTML del testo selezionato. Usa la funzione getSelectionHtml () da questa risposta: [ stackoverflow.com/a/4177234/4177020] E ora puoi sostituire questa stringa var selection = window.getSelection();con questa:var selection = getSelectionHtml();
Dmitry Kulahin

0

Anche una soluzione un po 'più breve:

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;
} );

0

È una raccolta di 2 risposte precedenti + compatibilità con Microsoft Edge.

Alla fine ho anche aggiunto un ripristino della selezione originale, come previsto per impostazione predefinita in qualsiasi browser.

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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.