有时候我们需要在用户复制网站内容时,给复制的内容加上一些而外的信息,比如网站和作者,起到维护版权和宣传的作用,这个需求还是挺有意思的。
实现的伪代码如下
window.addEventListener('copy', (e) => {
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const formatHTML = getFormatedHtml(getRangeHtml(range), extraData);
evt.clipboardData.setData('text/plain', getCopyText(getRangeHtml(range), extraData));
evt.clipboardData.setData('text/html', formatHTML);
})
上面代码中通过evt.clipboardData.setData
方法来修改clipboardData,以此达到增加二外信息的目的。但是这个有个缺点就是兼容性不够,不是所有浏览器器都能使用。
因此我们还需要一个hack
的方式来处理无法设置clipboardData
的情况,hack
的方式总结一句话就是移花接木,在copy
事件handle
中,通过Range.cloneContents()方法获取到用户选中的内容,并把clone
下来的内容与额外信息
一起塞到一个隐藏的div
中,这时候修改光标选中这个隐藏的div
,用户复制这个div
里的内容了,目的达成。
这个hack
方式需要注意的有两点:
- 事后需要恢复光标。
-
clone
下来的内容与额外信息
需要先用pre
标签包裹,以防止复制的格式丢失。
hackCopy(html, range) {
const dom = document.createElement('div');
dom.innerHTML = html;
dom.style.position = 'fixed';
dom.style.left = '-9999px';
document.body.appendChild(dom);
// 选中隐藏dom,这时候用户复制的就是这个dom的内容了
window.getSelection().selectAllChildren(dom);
setTimeout(() => {
try {
// 事后恢复光标
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
} catch (e) {}
document.body.removeChild(dom);
}, 0);
}
有了这个思路,完整实现web复制黏贴中添加额外信息的需求应该不难了
网友评论