Jak dodać dodatkowe informacje do skopiowanego tekstu internetowego

103

Niektóre witryny internetowe korzystają teraz z usługi JavaScript firmy Tynt, która dołącza tekst do kopiowanej zawartości.

Jeśli skopiujesz tekst z witryny za pomocą tego, a następnie wkleisz, otrzymasz link do oryginalnej treści na dole tekstu.

Tynt również to śledzi. To zgrabna sztuczka, dobrze wykonana.

Ich skrypt robiący to imponujące - zamiast próbować manipulować schowkiem (co tylko starsze wersje IE pozwalają im to robić domyślnie i który zawsze powinien być wyłączony), manipulują rzeczywistym wyborem.

Kiedy więc zaznaczysz blok tekstu, dodatkowa zawartość zostanie dodana jako ukryta <div>zawarta w Twoim zaznaczeniu. Po wklejeniu dodatkowy styl jest ignorowany i pojawia się dodatkowe łącze.

W rzeczywistości jest to dość łatwe do zrobienia w przypadku prostych bloków tekstu, ale jest to koszmar, gdy weźmie się pod uwagę wszystkie możliwe wybory w złożonym HTML w różnych przeglądarkach.

Tworzę aplikację internetową - nie chcę, aby ktokolwiek mógł śledzić kopiowane treści i chciałbym, aby dodatkowe informacje zawierały coś kontekstowego, a nie tylko łącze. W tym przypadku usługa Tynt nie jest odpowiednia.

Czy ktoś zna bibliotekę JavaScript typu open source (może wtyczkę jQuery lub podobną), która zapewnia podobną funkcjonalność, ale nie ujawnia wewnętrznych danych aplikacji?

Keith
źródło
1
Spójrz na moją odpowiedź na stackoverflow.com/questions/6344588/… . Robi się to bardzo podobnie, jak proponowałeś
Niklas
1
Zobacz także stackoverflow.com/questions/1203082/…
Gnubie,
48
Proszę, nie rób tego. PROSZĘ, PROSZĘ PROSZĘ, po prostu nie rób tego.
kanapa i
5
@couchand dlaczego nie? Rozumiem, jak irytujące jest to w witrynach ze spamem, ale dotyczy to aplikacji, której można używać do cytowania i gdzie dane wewnętrzne są poufne. Dlatego nie chciałem używać Tynt.
Keith
4
Czy na pewno chcesz to zrobić? Jako użytkownik nienawidzę tego i skieruję tę złość na Twój produkt: nie dotykaj mojego schowka!
aloisdg przenosi się na codidact.com

Odpowiedzi:

138

Aktualizacja 2020

Rozwiązanie, które działa we wszystkich najnowszych przeglądarkach.

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>


[Starszy post - przed aktualizacją 2020]

Istnieją dwa główne sposoby dodawania dodatkowych informacji do skopiowanego tekstu internetowego.

1. Manipulowanie wyborem

Chodzi o to, aby copy eventwyszukać plik, a następnie dołączyć do niego ukryty pojemnik z naszymi dodatkowymi informacjami domi rozszerzyć na niego wybór.
Ta metoda została zaadaptowana na podstawie tego artykułu przez c.bavota . Sprawdź też Jitbit „s wersji dla bardziej skomplikowanej sprawy.

  • Zgodność z przeglądarkami : wszystkie popularne przeglądarki, IE> 8.
  • Demo : jsFiddle demo .
  • Kod 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. Manipulowanie schowkiem

Chodzi o to, aby obserwować copy eventi bezpośrednio modyfikować dane ze schowka. Jest to możliwe przy użyciu clipboardDatanieruchomości. Należy pamiętać, że ta właściwość jest dostępna we wszystkich głównych przeglądarkach w read-only; setDatametoda jest dostępna tylko w IE.

  • Zgodność z przeglądarkami : IE> 4.
  • Demo : jsFiddle demo .
  • Kod 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
źródło
1
Twoje zdrowie! Niestety potrzebujemy, aby działał w IE, ale to nie jest zły początek.
Keith,
2
Nie powinno być obejście „<pre>” tagi, gładsza wersja tego skryptu jest tutaj
Alex
15
Zauważ, że "Manipulowanie schowkiem" działa doskonale w FireFox, Chrome i Safari, jeśli zmienisz window.clipboardDatana event.clipboardData. IE (także v11) nie obsługuje event.clipboardData jsfiddle.net/m56af0je/8
memy
3
Jeśli korzystasz z Google Analytics itp., Możesz nawet odpalić zdarzenie, aby zarejestrować, co użytkownicy kopiują z Twojej witryny. Ciekawe
geedubb
2
Pierwsza opcja ignoruje znaki nowego wiersza kopiowanego tekstu.
soham
7

To jest zwykłe rozwiązanie javascript ze zmodyfikowanego rozwiązania powyżej, ale obsługuje więcej przeglądarek (metoda 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);
GiorgosK
źródło
3

Najkrótsza wersja jQuery, którą przetestowałem i działa, to:

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
źródło
gdzie jest kod, który faktycznie kopiuje wynik do schowka?
vsync
@vsync Uważam, że to po prostu dodaje funkcjonalność tuż przed kopiowaniem (co jest wykonywane przez system, gdy użytkownik je inicjuje).
TerranRich
@vsync - jak powiedział TerraRich, próbowałem odpowiedzieć na pytanie, które dotyczyło dodania dodatkowych informacji do kopiowanego tekstu, więc rozwiązanie obejmuje tylko tę część.
user2276146
3

Oto wtyczka w jquery, która to robi https://github.com/niklasvh/jquery.plugin.clipboard Z pliku readme projektu "Ten skrypt modyfikuje zawartość zaznaczenia przed wywołaniem zdarzenia kopiowania, co powoduje skopiowanie zaznaczenia różni się od tego, co wybrał użytkownik.

Umożliwia to dołączanie / dodawanie treści do zaznaczenia, takich jak informacje o prawach autorskich lub inne treści.

Wydany na licencji MIT "

sktguha
źródło
1
To wygląda bardzo obiecująco. Używa on stylów wbudowanych, na które nie zezwalamy w naszym CSP, ale może zostać zaadaptowany. Twoje zdrowie!
Keith
3

Poprawiając odpowiedź, przywróć zaznaczenie po zmianach, aby zapobiec przypadkowym selekcjom po skopiowaniu.

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
źródło
@TsukimotoMitsumasa Powinno byćvar range = selection.getRangeAt(0);
Vokiel
Przywrócenie zaznaczenia tekstu jest dobrym pomysłem, w przeciwnym razie zepsuje domyślne zachowanie przeglądarki.
Sergey
2

Ulepszenie na 2018 rok

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
źródło
1
Podczas kopiowania i wklejania tracisz formatowanie ( <a> , <img> , <b> i inne tagi). Lepiej jest pobrać kod HTML zaznaczonego tekstu. Użyj funkcji getSelectionHtml () z tej odpowiedzi: [ stackoverflow.com/a/4177234/4177020] A teraz możesz zamienić ten ciąg var selection = window.getSelection();na ten:var selection = getSelectionHtml();
Dmitry Kulahin
0

Również trochę krótsze rozwiązanie:

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
źródło
0

To kompilacja 2 odpowiedzi powyżej + zgodność z Microsoft Edge.

Dodałem również przywrócenie oryginalnego zaznaczenia na końcu, tak jak jest to domyślnie oczekiwane w każdej przeglądarce.

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);
Siergiej
źródło