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

IT技术 javascript clipboard
2021-01-24 13:35:53

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

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

Tynt 也会在发生这种情况时对其进行跟踪。这是一个巧妙的技巧做得很好。

他们执行此操作的脚本令人印象深刻 - 而不是尝试操纵剪贴板(默认情况下只有旧版本的 IE 允许他们这样做并且应该始终关闭)他们操纵实际选择。

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

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

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

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

6个回答

2020 更新

适用于所有最新浏览器的解决方案

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>


[旧帖子 - 2020 年更新之前]

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

1. 操作选择

这个想法是观察copy event,然后将一个带有我们额外信息的隐藏容器附加到dom,并将选择扩展到它。
这种方法适合从本文c.bavota还要检查jitbit的版本以了解更复杂的情况。

  • 浏览器兼容性:所有主流浏览器,IE > 8。
  • 演示jsFiddle 演示
  • 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 > 4。
  • 演示jsFiddle 演示
  • 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);
如果您正在使用 Google Analytics 等,您甚至可以触发一个事件来记录用户从您的网站复制的内容。有趣的
2021-03-12 13:35:53
应该有“<前>”标签解决办法,这个脚本的平滑版本是在这里
2021-03-19 13:35:53
干杯! 不幸的是,我们需要它在 IE 中工作,但这并不是一个糟糕的开始。
2021-03-24 13:35:53
请注意,如果您更改window.clipboardDataevent.clipboardData. IE(也是 v11)不支持event.clipboardData jsfiddle.net/m56af0je/8
2021-03-26 13:35:53
第一个选项忽略复制文本的换行符。
2021-04-05 13:35:53

这是上述修改后的解决方案中的 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);

我测试过并正在工作的 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);
});
实际将结果复制到剪贴板的代码在哪里?
2021-03-13 13:35:53
@vsync 我相信这只是在复制发生之前添加功能(当用户启动时由系统完成)。
2021-03-29 13:35:53
@vsync - 正如 TerraRich 所说,我试图回答这个问题,这是关于在复制的文本中添加额外信息,所以解决方案只涵盖这部分。
2021-04-01 13:35:53

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

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

在 MIT 许可下发布”

这看起来很有希望。它使用了我们的 CSP 不允许使用的内联样式,但它可能会被调整。干杯!
2021-03-22 13:35:53

改进答案,在更改后恢复选择以防止复制后的随机选择。

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 应该有 var range = selection.getRangeAt(0);
2021-03-27 13:35:53
恢复文本选择是个好主意,否则会破坏浏览器的默认行为。
2021-04-06 13:35:53