前言
在复制有些网站的文章时,通常会发现,复制的内容还带了一个“小尾巴”,上边附带着版权信息。
例如:
作者:CoderLeiShuo
链接:https://juejin.im/user/4160207732875736
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在本篇文章中,尝试来实现一下这种效果。
大致原理就是在用户复制时,获取用户选中的将要复制的内容,然后再加上版权信息即可。
window.getSelection()
方法
如何获取用户复制的内容呢?我们可以通过window.getSelection()
方法,它返回一个**Selection
对象**,表示用户选择的文本范围或光标的当前位置。当然,你也可以用document.getSelection
,它们二者等价。
比如将光标置入上图中的搜索框,然后在控制台输入window.getSelection()
。返回的Selection
对象如下图所示:
?查阅Selection对象具体信息请点击此处
我们最终要获取的是选中区域的纯文本,而不是一个Seletion
对象。因此需要将Selection
对象转换成字符串,可以通过拼接一个空字符串或使用String.toString()
方法。
let selObj = window.getSelection();
let selectedTxt = selObj + '';
// 或者
let selectedTxt = selObj.toString();
我们在网页中尝试一下:
如上图所示:我们选择了网页中的部分内容,在控制台输入相关代码,看能否正确获取到选择内容的纯文本
可以看到,我们已经获取到了所选择的内容。
element.oncopy
事件
上一步操作中,我们已经成功获取到了选区中的文本内容。现在我们要开始实现复制时给复制的内容添加信息的效果了。
因此我们需要给element.oncopy
事件绑定相应的函数,实现相应功能。
oncopy
属性用来获取或设置当前元素的copy
事件的事件处理函数。注意,oncopy
属性是可以给其他元素进行设置的,不要因为我们一般都设置在window
或document
上,就认为它只能给它们设置。
我们先来看一个MDN上的例子:
<html>
<head>
<title>oncopy示例演示</title>
<script>
function log(txt)
{
// 以txt的值创建一个文本节点,作为子节点,追加到textarea元素中
document.getElementById("log").appendChild(document.createTextNode(txt + "\n"));
}
</script>
</head>
<body>
<div oncopy="log('复制被阻止!'); return false;">试着复制这句话!</div>
<h3>Log</h3>
<textarea rows="15" cols="80" id="log" readonly="true"></textarea>
</body>
</html>
当你尝试复制“试试复制这句话!”时,将会触发oncopy()
函数,在oncopy()
函数中,以传入的txt
的值创建了一个文本节点,作为子节点,追加到textarea
元素上了。因此,textarea
将会显示'复制被阻止'
字样!
并且由于return false;
语句使得复制的默认行为被取消,因此没有返回复制的内容。
第一次实现
通过前面内容的学习,我们可以做第一次尝试。通过window.selection()
方法获取选中的内容,然后为oncopy
绑定自定义的事件,在自定义事件中,把获取到的选区内容和我们的"小尾巴"信息进行拼接。
代码如下:
<!-- 第一次实现 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>在 JavaScript中,当一个对象被传递给期望字符串作为参数的函数中时(如 window.alert 或 document.write),对象的toString()方法会被调用,然后将返回值传给该函数。</p>
<p>实现很简单:取消默认复制之后,主要是在被复制的内容后面添加信息,然后根据 clipboardData 的 setData()方法将信息写入剪贴板</p>
<script>
document.oncopy = function () {
let selObj = window.getSelection();
// IE8及更早不支持window.getSelection
if (typeof selObj == 'undefined') return;
let selectedText = selObj + '';
// 如果选中文字内容小于30个字符,则不做任何操作
if (selectedText.length < 30) return;
let copytext = selectedText + 'CoderLeiShuo';
console.log(copytext);
}
</script>
</body>
</html>
可以看到,通过给oncopy
绑定自定义的事件,在事件代码执行后,输出了选区文本和'CoderLeiShuo'
拼接后的字符串。
那么,如果我们将copytext
返回出去,是不是就可以实现了呢?
于是,函数中加入return copytext;
语句。来看一下结果:
很不幸,粘贴的内容中还是选中的那些文字,并不是我们需要的拼接后的字符串
原因有两点:
- 给
oncopy
绑定的函数中,我们返回context
是没有用的,而应该返回false
,代表取消复制的默认行为。否则,无论你拼接什么的内容,剪贴板里的内容仍然只有你复制的那些。 - 但是当你取消复制事件的默认行为后,剪贴板就无法得到复制的内容,这就需要我们手动将拼接后的字符串写入剪贴板。
clipboardData
对象
取消默认的复制行为很好办,接下来,我们要详细研究一下剪贴板了。
clipboardData
对象:用于访问及修改剪贴板中的数据
不同浏览器,所属的对象不同:在 IE
中这个对象是window
对象的属性,在Chrome
、Safari
和Firefox
中,这个对象是相应的event
对象的属性。所以我们在使用的时候,需要做一下如下兼容
document.oncopy = e => {
let clipboardData = e.clipboardData || window.clipboardData;
// 获取clipboardData对象 + do something
}
对象方法
该对象有三个方法:getData()
、setData()
、clearData()
getData()
方法
getData()
方法接受一个format
参数,即要取得的数据的格式。数据类型有:text/plain
、text/uri-list
。
setData()
方法
setData()
方法授受两个参数,一个是format
参数,代表数据类型。第二个参数代表要放入剪贴板中的文本内容。这里我们可以指定format
参数为text/plain
,代表纯文本。
clearData()
方法
clearData()
方法接受一个可选参数format
,代表要删除的数据类型。如果此参数为空字符串或未提供,则删除所有类型的数据。
第二次实现
结合上面的内容,我们来做二次尝试。具体代码如下:
<!-- 第二次实现 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
p {
color: red;
font-size: 20px;
}
</style>
</head>
<body>
<p>在 JavaScript中,当一个对象被传递给期望字符串作为参数的函数中时(如 window.alert 或 document.write),对象的toString()方法会被调用,然后将返回值传给该函数。</p>
<p>实现很简单:取消默认复制之后,主要是在被复制的内容后面添加信息,然后根据 clipboardData 的 setData()方法将信息写入剪贴板</p>
<script>
document.oncopy = function (e) {
// 获取选区对象
let selObj = window.getSelection();
// IE8及更早不支持window.getSelection
if (typeof selObj == 'undefined') return false;
// 获取clipboardData对象
// Chrome\Safari\Firefox浏览器中,这个对象是event对象的属性
// IE浏览器中,它是window对象的属性
let clipboardData = e.clipboardData || window.clipboardData;
// 获取选区文本内容
let selectedText = selObj + '';
let copytext;
// 如果选中文字内容小于30个字符,则不做任何操作
if (selectedText.length < 30) {
copytext = selectedText;
} else {
copytext = selectedText +
'\n\n\n' +
'作者:CoderLeiShuo\n' +
'链接:' + location.href + '\n' +
'来源:掘金\n' +
'著作权归作者所有。商业转载请联系作者获取授权,非商业转载请注明出处。';
}
// setData(format,text)用于设置剪贴板内容
clipboardData.setData('text/plain', copytext);
// 取消默认的复制事件
return false;
// e.preventDefault()亦可
}
</script>
</body>
</html>
来看一下效果:
后续
至此,我们已经实现了基本的功能,但是目前的代码还没有兼容低版本的IE浏览器,并且还没有实现带格式复制的功能。后续将继续进行完善。本人能力有限,如文章内容有错,敬请指正!谢谢!
参考文章
本篇文章在写作过程中,参考了以下文章的内容。正是站在前辈们的肩膀上,才有了这篇文章,感谢各位前辈!
JavaScript中的复制粘贴功能
MDN element.oncopy
复制网页内容自动添加版权信息的方法(兼容IE所有版本)
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!