持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
9月30日,天气晴,截止到下午17:50分终于闲下来了,摸鱼时间终于到了。
需求
最近公司在搞复制文本标识网站版权,使用户粘贴到文本后面追加一些来源和作者相关的描述。。。 就像粘贴掘金里面的文章的时候,后面会追加这么一坨。
有些细心的人才会发现,粘贴到富文本中的样式和普通文本的样式是不同的。
其实,这个问题我们平时可能真的不会关注,直到我们做的时候才会在乎这些细节。
知识点
拷贝文本这个底层会有两份数据,一种是html格式数据,一种是text格式数据,当复制目标域是富文本时,会默认使用html结构数据,当复制域是普通文本域时,会使用text格式数据
过程
毕竟现在能搜到所有答案。直接交给百度吧,百度搜索的姿势可能不对。搜了很到,大多都一样。结果只是复制文本,复制到富文本中样式直接丢失。 这可急坏了小白我,好在最终一口气抽了20盒烟,总算是百度出来一个方案。 方案,
- 劫持dom或者body的copy事件。组织默认事件。
- 然后通过
window.getSelection获取选中的元素。拷贝一份选区的Domwindow.getSelection().getRangeAt(0).cloneContents(),在内存中创建一个div节点。用这个div将用户选中的区域的html和我们要追加的html包裹起来,var htmlData = <div>${node.innerHTML}${this.data.html}</div>;(显得干净,虽然看不到,但是我觉得很有必要)。 - 和上一步骤一样,上一个步骤是为了拼接富文本粘贴的数据,这次是把innerText合并到一起。供给普通文本域复制时使用。
- 修改事件对象中默认数据。上面得到我们拼接好的数据,然后设置一下即可,设置普通文本数据:
event.clipboardData.setData("text/plain", textData),设置富文本数据:event.clipboardData.setData("text/html", htmlData) - 有些老浏览器不支持event.clipboardData,会在window.clipboardData中存储剪切板数据。兼容一下即可。没有富文本数据时会自动降级为普通文本。
具体代码如下。请自取
event.preventDefault();
var node = document.createElement('div');
node.appendChild(window.getSelection().getRangeAt(0).cloneContents());
//getRangeAt(0)返回对基于零的数字索引与传递参数匹配的选择对象中的范围的引用。对于连续选择,参数应为零。
var htmlData = `<div>${node.innerHTML}${html}</div>`;
var textData = window.getSelection().getRangeAt(0) + text;
if (event.clipboardData) {
// html是数据拷贝到富文本时的值
event.clipboardData.setData("text/html", htmlData);
//setData(剪贴板格式, 数据) 给剪贴板赋予指定格式的数据。返回 true 表示操作成功。
event.clipboardData.setData("text/plain", textData);
} else if (window.clipboardData) {
//window.clipboardData的作用是在页面上将需要的东西复制到剪贴板上,提供了对于预定义的剪贴板格式的访问,以便在编辑操作中使用。
return window.clipboardData.setData("text", textData);
}
}
function addClipboardCopyright(select, html, text) {
let node = document.querySelector(select) || document.body
node.addEventListener('copy', function (e) {
setClipboard(e, html, text);
});
}
let html =
`著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。作者:<a href="https://www.wanlishipin.cn/">李老汉</a><br />来源: <a href="https://www.wanlishipin.cn/">山西</a>`;
let text = `\n\n著作权归作者所有。\n商业转载请联系作者获得授权,非商业转载请注明出处。\n作者:李老汉\n来源:山西`;
addClipboardCopyright('#markdown-body', html, text)
end
demo就展示了。最终效果如下 复制对象
复制到普通文本区域
复制到富文本区域