前言
在复制有些网站的文章时,通常会发现,复制的内容还带了一个“小尾巴”,上边附带着版权信息。
例如:
1 | 作者:CoderLeiShuo |
在本篇文章中,尝试来实现一下这种效果。
大致原理就是在用户复制时,获取用户选中的将要复制的内容,然后再加上版权信息即可。
window.getSelection()
方法
如何获取用户复制的内容呢?我们可以通过window.getSelection()
方法,它返回一个Selection
对象,表示用户选择的文本范围或光标的当前位置。当然,你也可以用document.getSelection
,它们二者等价。
比如将光标置入上图中的搜索框,然后在控制台输入window.getSelection()
。返回的Selection
对象如下图所示:
我们最终要获取的是选中区域的纯文本,而不是一个Seletion
对象。因此需要将Selection
对象转换成字符串,可以通过拼接一个空字符串或使用String.toString()
方法。
1 | let selObj = window.getSelection(); |
我们在网页中尝试一下:
如上图所示:我们选择了网页中的部分内容,在控制台输入相关代码,看能否正确获取到选择内容的纯文本
可以看到,我们已经获取到了所选择的内容。
window.getSelection()
在IE8及以下的浏览器上不支持
element.oncopy
事件
上一步操作中,我们已经成功获取到了选区中的文本内容。现在我们要开始实现复制时给复制的内容添加信息的效果了。
因此我们需要给element.oncopy
事件绑定相应的函数,实现相应功能。
oncopy
属性用来获取或设置当前元素的copy
事件的事件处理函数。注意,oncopy
属性是可以给其他元素进行设置的,不要因为我们一般都设置在window
或document
上,就认为它只能给它们设置。
我们先来看一个MDN上的例子:
1 | <html> |
当你尝试复制“试试复制这句话!”时,将会触发oncopy()
函数,在oncopy()
函数中,以传入的txt
的值创建了一个文本节点,作为子节点,追加到textarea
元素上了。因此,textarea
将会显示'复制被阻止'
字样!
并且由于return false;
语句使得复制的默认行为被取消,因此没有返回复制的内容。
第一次实现
通过前面内容的学习,我们可以做第一次尝试。通过window.selection()
方法获取选中的内容,然后为oncopy
绑定自定义的事件,在自定义事件中,把获取到的选区内容和我们的”小尾巴”信息进行拼接。
代码如下:
1 | <!-- 第一次实现 --> |
可以看到,通过给oncopy
绑定自定义的事件,在事件代码执行后,输出了选区文本和'CoderLeiShuo'
拼接后的字符串。
那么,如果我们将copytext
返回出去,是不是就可以实现了呢?
于是,函数中加入return copytext;
语句。来看一下结果:
很不幸,粘贴的内容中还是选中的那些文字,并不是我们需要的拼接后的字符串
原因有两点:
- 给
oncopy
绑定的函数中,我们返回context
是没有用的,而应该返回false
,代表取消复制的默认行为。否则,无论你拼接什么的内容,剪贴板里的内容仍然只有你复制的那些。 - 但是当你取消复制事件的默认行为后,剪贴板就无法得到复制的内容,这就需要我们手动将拼接后的字符串写入剪贴板。
clipboardData
对象
取消默认的复制行为很好办,接下来,我们要详细研究一下剪贴板了。
clipboardData
对象:用于访问及修改剪贴板中的数据
不同浏览器,所属的对象不同:在 IE
中这个对象是window
对象的属性,在Chrome
、Safari
和Firefox
中,这个对象是相应的event
对象的属性。所以我们在使用的时候,需要做一下如下兼容
1 | document.oncopy = e => { |
对象方法
该对象有三个方法:getData()
、setData()
、clearData()
getData()
方法
getData()
方法接受一个format
参数,即要取得的数据的格式。数据类型有:text/plain
、text/uri-list
。
setData()
方法
setData()
方法授受两个参数,一个是format
参数,代表数据类型。第二个参数代表要放入剪贴板中的文本内容。这里我们可以指定format
参数为text/plain
,代表纯文本。
clearData()
方法
clearData()
方法接受一个可选参数format
,代表要删除的数据类型。如果此参数为空字符串或未提供,则删除所有类型的数据。
第二次实现
结合上面的内容,我们来做二次尝试。具体代码如下:
1 | <!-- 第二次实现 --> |
来看一下效果:
后续
至此,我们已经实现了基本的功能,但是目前的代码还没有兼容低版本的IE浏览器,并且还没有实现带格式复制的功能。后续将继续进行完善。
参考文章
本篇文章在写作过程中,参考了以下文章的内容。
本文作者: CoderLeiShuo
本文链接:https://coderleishuo.github.io/lele/16327.html
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!