Kopyalanan web metnine fazladan bilgi nasıl eklenir?


103

Bazı web siteleri artık Tynt'in kopyalanan içeriğe metin ekleyen bir JavaScript hizmeti kullanıyor .

Bunu kullanarak bir siteden metin kopyalar ve ardından yapıştırırsanız, metnin altındaki orijinal içeriğe bir bağlantı alırsınız.

Tynt bunu olduğu gibi de izler. İyi yapılmış güzel bir numara.

Bunu yapmak için yazdıkları komutlar etkileyicidir - panoyu değiştirmeye çalışmak yerine (ki bu sadece IE'nin eski sürümleri varsayılan olarak yapmalarına izin verir ve her zaman kapatılmalıdır) gerçek seçimi değiştirirler.

Dolayısıyla, bir metin bloğu seçtiğinizde, fazladan içerik <div>seçiminize gizli olarak eklenir . Yapıştırdığınızda ekstra stil yok sayılır ve fazladan bağlantı görünür.

Bunu basit metin bloklarıyla yapmak aslında oldukça kolaydır, ancak farklı tarayıcılarda karmaşık HTML'de olası tüm seçimleri düşündüğünüzde bir kabus olur.

Bir web uygulaması geliştiriyorum - kimsenin kopyalanan içeriği izleyebilmesini istemiyorum ve ekstra bilgilerin sadece bir bağlantı yerine bağlamsal bir şey içermesini istiyorum. Tynt'in hizmeti bu durumda pek uygun değil.

Benzer işlevler sağlayan ancak dahili uygulama verilerini açığa çıkarmayan açık kaynaklı bir JavaScript kitaplığı (belki bir jQuery eklentisi veya benzeri) bilen var mı?


1
Cevabıma stackoverflow.com/questions/6344588/… adresinden bir göz atın . Önerdiğinize çok benzer şekilde yapıldı
Niklas


48
Lütfen bunu yapmayın. LÜTFEN LÜTFEN LÜTFEN lütfen yapma.
couchand

5
@couchand neden olmasın? Bunun spam sitelerinde ne kadar can sıkıcı olduğunu anlıyorum, ancak bu alıntılar için kullanılabilecek ve dahili verilerin hassas olduğu bir uygulama için. Bu yüzden Tynt'i kullanmak istemedim.
Keith

4
Bunu yapmak istediğine emin misin? Bir kullanıcı olarak bundan nefret ediyorum ve bu öfkeyi ürününüze aktaracağım: Panoma dokunmayın!
aloisdg codidact.com'a taşınıyor

Yanıtlar:


138

2020 Güncellemesi

Tüm yeni tarayıcılarda çalışan çözüm .

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>


[Eski gönderi - 2020 güncellemesinden önce]

Kopyalanan web metnine fazladan bilgi eklemenin iki ana yolu vardır.

1. Seçimi değiştirme

Buradaki fikir, için izlemek copy event, daha sonra ekstra bilgilerimizle gizli bir kapsayıcı eklemek domve seçimi ona genişletmektir.
Bu yöntem, bu makaleden c.bavota tarafından uyarlanmıştır . Daha karmaşık durum için jitbit'in sürümünü de kontrol edin .

  • Tarayıcı Uyumluluğu : Tüm büyük tarayıcılar, IE> 8.
  • Demo : jsFiddle demosu .
  • Javascript kodu :

    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. Panoyu değiştirme

Buradaki fikir, copy eventpano verilerini izlemek ve doğrudan değiştirmektir. Bu clipboardDataözelliği kullanarak mümkündür . Bu özelliğin tüm büyük tarayıcılarda mevcut olduğunu unutmayın read-only; setDatayöntem IE kullanılabilir.

  • Tarayıcı uyumluluğu : IE> 4.
  • Demo : jsFiddle demosu .
  • Javascript kodu :

    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
Şerefe! Ne yazık ki IE'de çalışmasına ihtiyacımız var, ancak bu kötü bir başlangıç ​​değil.
Keith

2
"<pre>" etiketleri için bir geçici çözüm olmalı, bu komut dosyasının daha sorunsuz bir sürümü burada
Alex

15
"Panoyu değiştirme" seçeneğinin FireFox, Chrome ve Safari'de değiştirirseniz mükemmel window.clipboardDataşekilde çalıştığını unutmayın event.clipboardData. IE (v11 de) event.clipboardData jsfiddle.net/m56af0je/8'i
mems

3
Google Analytics vb. Kullanıyorsanız, kullanıcıların sitenizden ne kopyaladığını kaydetmek için bir olay bile başlatabilirsiniz. İlginç
geedubb

2
İlk seçenek, kopyalanan metnin yeni satır karakterlerini göz ardı eder.
soham

7

Bu, yukarıdaki değiştirilmiş bir çözümden elde edilen bir vanilya javascript çözümüdür, ancak daha fazla tarayıcıyı destekler (çapraz tarayıcı yöntemi)

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

Test ettiğim ve çalıştığım jQuery için en kısa sürüm:

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

gerçekten sonucu panoya kopyalayan kod nerede?
vsync

@vsync Bunun, kopyalama gerçekleşmeden hemen önce işlevsellik eklediğine inanıyorum (bu, kullanıcı başlattığında sistem tarafından yapılır).
TerranRich

@vsync - TerraRich'in dediği gibi, kopyalanan metne fazladan bilgi eklemekle ilgili soruya yanıt vermeye çalıştım, bu nedenle çözüm yalnızca bu bölümü kapsar.
user2276146

3

İşte bunu yapmak için jquery'de bir eklenti https://github.com/niklasvh/jquery.plugin.clipboard Proje benioku sayfasından "Bu komut dosyası, bir kopyalama olayı çağrılmadan önce bir seçimin içeriğini değiştirerek, kopyalanmış seçimle sonuçlanır kullanıcının seçtiğinden farklı olmak.

Bu, telif hakkı bilgileri veya diğer içerikler gibi seçime içerik eklemenize / içeriğin başına eklemenize olanak tanır.

MIT Lisansı altında yayınlandı "


1
Bu çok umut verici görünüyor. CSP'mizde izin vermediğimiz satır içi stilleri kullanır, ancak potansiyel olarak uyarlanabilir. Şerefe!
Keith

3

Yanıtı iyileştirerek, kopyalamadan sonra rastgele seçimleri önlemek için değişikliklerden sonra seçimi geri yükleyin.

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 Olmalıvar range = selection.getRangeAt(0);
Vokiel

Metin seçimini geri yüklemek iyi bir fikirdir, aksi takdirde varsayılan tarayıcı davranışını bozar.
Sergey

2

2018 İyileştirme

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
Kopyalayıp yapıştırdığınızda biçimlendirmeyi kaybedersiniz ( <a> , <img> , <b> ve diğer etiketler). Seçili metnin HTML kodunu almak daha iyidir. Bu yanıttan getSelectionHtml () işlevini kullanın : [ stackoverflow.com/a/4177234/4177020] Ve şimdi bu dizeyi var selection = window.getSelection();var selection = getSelectionHtml();
bununla

0

Ayrıca biraz daha kısa bir çözüm:

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

Yukarıdaki 2 cevabın ve Microsoft Edge ile uyumluluğun bir derlemesidir.

Ayrıca, herhangi bir tarayıcıda varsayılan olarak beklendiği gibi, en sonunda orijinal seçimin bir geri yüklemesini de ekledim.

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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.