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?


1
Spójrz na moją odpowiedź na stackoverflow.com/questions/6344588/… . Robi się to bardzo podobnie, jak proponowałeś
Niklas


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

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

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

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 "


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

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

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

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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.