如何向复制的Web文本添加额外信息

时间:2010-01-08 08:33:13

标签: javascript clipboard

有些网站现在使用Tynt中的JavaScript服务,该服务会将文字附加到复制的内容中。

如果您使用此功能从网站复制文本然后粘贴,则会在文本底部获得指向原始内容的链接。

Tynt也会跟踪它。这是一个很好的技巧。

他们这样做的脚本令人印象深刻 - 而不是试图操纵剪贴板(只有旧版本的IE允许他们默认执行,而且应该总是关闭)他们操纵实际选择。

因此,当您选择一个文本块时,额外内容会添加为您选择中包含的隐藏<div>。粘贴时,将忽略额外的样式,并显示额外的链接。

这对于简单的文本块实际上相当容易,但是当您考虑在不同浏览器中复杂HTML中的所有选择时,这是一场噩梦。

我正在开发一个Web应用程序 - 我不希望任何人能够跟踪复制的内容,我希望额外的信息包含某些上下文,而不仅仅是一个链接。在这种情况下,Tynt的服务并不合适。

有没有人知道开源JavaScript库(可能是jQuery插件或类似的)提供类似功能但不暴露内部应用程序数据?

7 个答案:

答案 0 :(得分:115)

有两种主要方法可以为复制的网络文字添加额外信息。

1。操纵选择

我们的想法是观察copy event,然后将包含我们额外信息的隐藏容器添加到dom,并将选择范围扩展到它。
此方法改编自 c.bavota this article。另请查看jitbit's version以了解更复杂的案例。

  • 浏览器兼容性:所有主流浏览器,IE&gt; 8。
  • 演示jsFiddle demo
  • 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。操纵剪贴板

想法是观察copy event并直接修改剪贴板数据。这可以使用clipboardData属性。请注意,此属性适用于read-only中的所有主要浏览器; setData方法仅适用于IE。

  • 浏览器兼容性:IE&gt; 4。
  • 演示jsFiddle demo
  • 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 :(得分:4)

这是一个来自上述修改过的解决方案的vanilla javascript解决方案,但支持更多浏览器(跨浏览器方法)

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

答案 2 :(得分:3)

我测试并正在运行的jQuery的最短版本是:

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

答案 3 :(得分:3)

这是jquery中的一个插件 https://github.com/niklasvh/jquery.plugin.clipboard 从项目自述 “此脚本在调用复制事件之前修改选择内容,导致复制的选择与用户选择的选择不同。

这允许您在选择中附加/添加内容,例如版权信息或其他内容。

根据麻省理工学院许可证发布“

答案 4 :(得分:1)

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

答案 5 :(得分:0)

也是一个更短的解决方案:

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

答案 6 :(得分:0)

这是以上2个答案的汇编+与Microsoft Edge的兼容性。

我还在最后添加了原始选择的恢复,因为在任何浏览器中都是默认的。

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