So fügen Sie kopiertem Webtext zusätzliche Informationen hinzu

103

Einige Websites verwenden jetzt einen JavaScript-Dienst von Tynt , der Text an kopierte Inhalte anfügt.

Wenn Sie damit Text von einer Site kopieren und dann einfügen, erhalten Sie einen Link zum Originalinhalt am Ende des Textes.

Tynt verfolgt dies auch, wenn es passiert. Es ist ein ordentlicher Trick, der gut gemacht ist.

Ihr Skript dafür ist beeindruckend - anstatt zu versuchen, die Zwischenablage zu manipulieren (was nur ältere Versionen von IE standardmäßig zulassen und die immer deaktiviert sein sollten), manipulieren sie die eigentliche Auswahl.

Wenn Sie also einen Textblock auswählen, wird der zusätzliche Inhalt als versteckter Inhalt <div>in Ihre Auswahl aufgenommen. Wenn Sie einfügen, wird der zusätzliche Stil ignoriert und der zusätzliche Link wird angezeigt.

Dies ist eigentlich ziemlich einfach mit einfachen Textblöcken zu tun, aber ein Albtraum, wenn man alle Auswahlmöglichkeiten berücksichtigt, die für komplexes HTML in verschiedenen Browsern möglich sind.

Ich entwickle eine Webanwendung - ich möchte nicht, dass jemand den kopierten Inhalt verfolgen kann, und ich möchte, dass die zusätzlichen Informationen etwas Kontextuelles und nicht nur einen Link enthalten. Der Service von Tynt ist in diesem Fall nicht wirklich angemessen.

Kennt jemand eine Open-Source-JavaScript-Bibliothek (möglicherweise ein jQuery-Plug-In oder ähnliches), die ähnliche Funktionen bietet, jedoch keine internen Anwendungsdaten verfügbar macht?

Keith
quelle
1
Schauen Sie sich meine Antwort unter stackoverflow.com/questions/6344588/… an . Es wird sehr ähnlich gemacht, wie Sie vorgeschlagen haben
Niklas
48
Bitte tu das nicht. BITTE BITTE BITTE einfach nicht.
Couch und
5
@couchand warum nicht? Ich verstehe, wie ärgerlich dies auf Spam-Sites ist, aber dies ist für eine Anwendung, die für Zitate verwendet werden kann und bei der die internen Daten vertraulich sind. Deshalb wollte ich Tynt nicht verwenden.
Keith
4
Sind Sie sicher, dass Sie dies tun möchten? Als Benutzer hasse ich es und werde diesen Ärger in Ihr Produkt portieren: Berühren Sie nicht meine Zwischenablage!
Aloisdg wechselt zu codidact.com

Antworten:

138

2020 Update

Lösung, die auf allen aktuellen Browsern funktioniert .

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>


[Älterer Beitrag - vor dem Update 2020]

Es gibt zwei Möglichkeiten, dem kopierten Webtext zusätzliche Informationen hinzuzufügen.

1. Bearbeiten der Auswahl

Die Idee ist, nach dem zu copy eventsuchen, dann einen versteckten Container mit unseren zusätzlichen Informationen an das anzuhängen domund die Auswahl darauf zu erweitern.
Diese Methode wurde aus diesem Artikel von c.bavota angepasst . Überprüfen Sie auch die Version von jitbit auf komplexere Fälle.

  • Browserkompatibilität : Alle gängigen Browser, IE> 8.
  • Demo : jsFiddle-Demo .
  • Javascript-Code :

    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. Bearbeiten der Zwischenablage

Die Idee ist, copy eventdie Zwischenablagedaten zu beobachten und direkt zu ändern. Dies ist über die clipboardDataEigenschaft möglich. Beachten Sie, dass diese Eigenschaft in allen gängigen Browsern in verfügbar ist read-only. Die setDataMethode ist nur im IE verfügbar.

  • Browserkompatibilität : IE> 4.
  • Demo : jsFiddle-Demo .
  • Javascript-Code :

    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
quelle
1
Prost! Leider muss es im IE funktionieren, aber das ist kein schlechter Start.
Keith
2
Es sollte eine Problemumgehung für "<pre>" - Tags geben. Eine flüssigere Version dieses Skripts finden Sie hier
Alex,
15
Beachten Sie, dass „Manipulieren der Zwischenablage“ arbeitet prefectly in FireFox, Chrome und Safari , wenn Sie ändern window.clipboardDatazu event.clipboardData. IE (auch v11) unterstützt event.clipboardData jsfiddle.net/m56af0je/8
mems
3
Wenn Sie Google Analytics usw. verwenden, können Sie sogar ein Ereignis auslösen, um zu protokollieren, welche Benutzer von Ihrer Website kopieren. Interessant
geedubb
2
Die erste Option ignoriert die neuen Zeilenzeichen des kopierten Textes.
Soham
7

Dies ist eine Vanille-Javascript-Lösung aus einer der oben modifizierten Lösungen, unterstützt jedoch mehr Browser (Cross-Browser-Methode)

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
quelle
3

Die kürzeste Version für jQuery, die ich getestet habe und die funktioniert, ist:

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
quelle
Wo ist der Code, der das Ergebnis tatsächlich in die Zwischenablage kopiert?
vsync
@vsync Ich glaube, dies fügt nur Funktionen hinzu, kurz bevor das Kopieren stattfindet (was vom System durchgeführt wird, wenn der Benutzer es initiiert).
TerranRich
@vsync - Wie TerraRich sagte, habe ich versucht, auf die Frage zu antworten, bei der es darum ging, zusätzliche Informationen in kopierten Text einzufügen, sodass die Lösung nur diesen Teil abdeckt.
user2276146
3

Hier ist ein Plugin in jquery, um dies zu tun. Https://github.com/niklasvh/jquery.plugin.clipboard Aus der Projekt-Readme- Datei "Dieses Skript ändert den Inhalt einer Auswahl, bevor ein Kopierereignis aufgerufen wird, was zur kopierten Auswahl führt anders sein als das, was der Benutzer ausgewählt hat.

Auf diese Weise können Sie der Auswahl Inhalte anhängen / voranstellen, z. B. Copyright-Informationen oder andere Inhalte.

Veröffentlicht unter MIT-Lizenz "

sktguha
quelle
1
Das sieht sehr vielversprechend aus. Es werden Inline-Stile verwendet, die wir mit unserem CSP nicht zulassen, die jedoch möglicherweise angepasst werden könnten. Prost!
Keith
3

Verbessern Sie die Antwort und stellen Sie die Auswahl nach den Änderungen wieder her, um eine zufällige Auswahl nach dem Kopieren zu verhindern.

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);
digitalPBK
quelle
@ TsukimotoMitsumasa Es solltevar range = selection.getRangeAt(0);
Vokiel
Das Wiederherstellen der Textauswahl ist eine gute Idee, da sonst das Standardverhalten des Browsers verletzt wird.
Sergey
2

Verbesserung für 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();
});
tronic
quelle
1
Beim Kopieren und Einfügen verlieren Sie die Formatierung ( <a> , <img> , <b> und andere Tags). Es ist besser, HTML-Code für ausgewählten Text zu erhalten. Verwenden Sie die Funktion getSelectionHtml () aus dieser Antwort: [ stackoverflow.com/a/4177234/4177020] Und jetzt können Sie diese Zeichenfolge var selection = window.getSelection();durch diese ersetzen :var selection = getSelectionHtml();
Dmitry Kulahin
0

Auch eine etwas kürzere Lösung:

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;
} );
Almo
quelle
0

Es ist eine Zusammenstellung von 2 Antworten oben + Kompatibilität mit Microsoft Edge.

Ich habe am Ende auch eine Wiederherstellung der ursprünglichen Auswahl hinzugefügt, wie dies standardmäßig in jedem Browser erwartet wird.

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