搞定!让你轻松掌握JS自动复制内容的多种方法
一、前言
现在很多网站,尤其是技术性强的论坛、博客等,用户都可能有大量复制需求。但用户手动复制在内容不止一屏时很不方便,且一些网站的设计可能导致用户无法正确复制内容。因此,就需要使用脚本复制内容,实现点击按钮自动复制的效果。
本文大部分属性及方法参考MDN开发者文档,并有对应页面的链接,可供参考。
注:末尾附录有无注释的源代码,可直接在项目中使用。
二、设置剪贴板数据[IE Only]
显然,最方便的方法便是直接设置剪贴版的数据。在IE中暴露了 window.clipboardData 属性,可获取到一个表示剪贴版数据的对象。
这个对象的类型,至少在符合规范的新版本中是DataTransfer。在剪贴版这一例中,用到的该借口的函数有三个:
-
getData(type),获取指定
type
类型的数据值。 -
setData(type,data),设置指定
type
类型的数据值为value
。 -
clearData([type]),清空指定
type
类型的数据。如果不提供参数,则清空所有数据。
要注意该type
不是通常意义的key
,它的取值是固定的,如 text/plain
(可直接使用 text
), text/html
, text/uri-list
等,显然是指 MIME 类型。
于是,简单地使用以下代码便可自动复制内容:
window.clipboardData.setData("text",data);
当然,这很不安全。因此,只有IE支持它。
三、选区操作
显然,上述操作剪贴版的方式使得用户在不同位置的数据暴露给未知的第三方。所以大多数浏览器禁止了这一操作。但是,至少单纯地复制选中区域风险不大,这通常是被允许的。
但是,这就要求系统将选区调整到某个包含所需文本的区域,然后再设法触发复制操作。如果自动复制功能只是复制现成的元素,并且内容是连续的话(目前只有Firefox允许多个区域同时选中,并且复制的内容无法保证正确),直接将选区调整到该段区域即可。
但大多数情况下我们需要像 setData
方法那样复制特定文本,还要防止各种元素被错误复制。因此,就需要创建一个临时的文本节点,从而达到复制的效果。
基本的复制函数如下(下附无注释完整版):
function copy(data) {
var sel = window.getSelection(); //获取Selection对象
var range = document.createRange(); //创建Range对象
var node = document.createTextNode(data); //创建文本节点,并指定内容
document.body.appendChild(node); //加入body末尾(否则无法选中)
range.selectNode(node); //选中文本节点
sel.removeAllRanges(); //删除原先选区
sel.addRange(range); //将区域加入选区
document.execCommand("copy"); //execCommand执行复制操作
document.body.removeChild(node); //删除临时节点
}
copy("该文本将会被复制");
其中,execCommand 是用于对文档执行特定命令的方法。使用 copy
命令可指定复制当前选中区域。
另外,注意 cut
命令在非IE浏览器不能用于删除不可编辑元素,因此应使用 copy
+ 删除元素确保元素被从文档删除。
解析
该函数的意义十分清晰:
- 获取选区对象,并创建一个
Range
区域; - 创建一个文本节点,内容为指定复制的文本;
- 将节点加入
body
末尾,然后设置区域包括该节点; - 将原有选区清除,并将新创建的选区加入;
- 执行复制命令,然后把临时新增的节点删除。
当然,该版本还未优化兼容性,并且会导致原有选区清除。因此,笔者在附录中新增了一个完整版本。
其中,Selection 是目前主流浏览器(IE 9+)都支持的,用于表示选择区域的接口。当前选区对象可使用 window.getSelection() 方法获取。
比较重要的 Selection 属性和方法有:
- anchorNode focusNode,获取选区锚点(按住开始选中的点)及焦点(松开结束选中的点)各自所在的节点。注意锚点不一定在焦点之前。
- anchorOffset focusOffset,获取选区锚点及焦点在所在节点的偏移量。如果把文本节点中每个字符看作一个子节点,则该值可看作边界点在所在节点的第几个子节点之后。
- isCollapsed,返回选区是否折叠(即锚点与焦点是否位于同一点)。折叠的选区可以用于表示插入光标(Caret)的位置!
- getRangeAt(index),获取指定下标的 Range 的引用。
还有一个重要的 Range 对象,它表示文档的某一区域,Selection 就是用它处理选区。顺便要注意,一个 Selection 可能有多个 Range,也就是用户按住Ctrl键选中多个区域时(目前除Firefox外的浏览器都禁止多个选区)。
Range 的属性中,有 Range.startContainer
Range.startOffset
Range.endContainer
Range.endOffset
属性,显然和刚刚 Selection 对应的属性意义相同,此处不赘述。
重要的部分方法有:
-
setStart(node,offset) setEnd(node,offset),将区域的起点/终点设在
node
节点内,偏移量为offset
处。 -
selectNode(node),使区域包含
node
节点及其内容。 -
insertNode(node),在区域之前插入
node
节点,并包括该新增节点。
因此,灵活使用这些方法,就能实现简单的内容自动复制。当然,IE9以下必须使用 document.selection 处理,这在DHTML文档中有详细说明,此处不再赘述。
附录
完整的复制函数如下(兼容IE 4+)。
function copy(data){
if(window.clipboardData){
window.clipboardData.setData("text",data);
}
else if(document.execCommand){
if(document.selection){
var sel = document.selection,srange = sel.createRange();
var range = document.createTextRange();
var node = document.createElement("span");
var temp = document.body.createTextNode(data);
node.style.display = "none";
node.appendChild(temp);
document.body.appendChild(node);
range.moveToElementText(node);
range.select();
document.execCommand("copy");
srange.select();
document.body.removeChild(node);
}
else if(window.getSelection){
var sel = window.getSelection(),srange = [];
var range = document.createRange();
var node = document.body.createTextNode(data);
for(var i=0; i<sel.rangeCount; i++) {
srange[i]=sel.getRangeAt(i);
}
document.body.appendChild(node);
range.selectNode(node);
sel.removeAllRanges();
sel.addRange(range);
document.execCommand("copy");
document.body.removeChild(node);
sel.removeAllRanges();
for(var i in srange) {
sel.addRange(srange[i]);
}
}
}
}
下一篇: 简单易学!JS如何轻松实现一键复制功能?
推荐阅读
-
Adobe国际认证中文官方网站】Adobe中国摄影计划,免费安装正版激活--Adobe Creative Cloud中国摄影计划。与此同时,Adobe宣布天猫为Adobe Creative Cloud中国摄影计划的电商战略合作伙伴,并将与其合作上线Adobe天猫官方旗舰店。 此举无疑一方面扩大了Adobe在中国的影响力,另一方面也有助于国内用户更好地培养正版软件意识,推动Adobe软件在中国的正版化进程。 网络异常,图片无法显示 ||网络异常 Adobe Creative Cloud中国摄影计划包括Photoshop和Lightroom Classic两大桌面创意工具,以及iOS版Photoshop Express。 其中,Adobe Lightroom Classic和Adobe Photoshop作为两款常用的图像处理软件,对于那些玩摄影、后期修图的创意设计人群无疑有着巨大的帮助,而LR+PS套装对于摄影领域用户的重要性自不必说,正版产品的性能实时更新也可以放心!体验最新功能,对于新镜头(补偿)和机身(RAW 读取)都能第一时间适应。不信你看: Photoshop 图像合成 裁剪、移除对象、润饰合成照片、玩转色彩和特效,创建精美图片和艺术品! Lightroom Classic 照片编辑 轻松批量管理和编辑照片,内置专业创意控件和摄影师预设,让你的照片大放异彩。 手机 PS 便捷编辑 Photoshop Express 支持多种滤镜、贴纸,手机即可完成抠图、除雾等任务 人工智能编辑工具 神经滤镜、快速点击选区、自动选择主题等人工智能功能让图像编辑更轻松 创意画笔内容识别 定制艺术画笔工具,实现个性化效果;内容识别填充,智能去除无用物体。 Adobe Creative Cloud 中国摄影计划的推出,为中国的专业摄影师、摄影爱好者、后期修图和其他创意设计人员带来了全方位的内容和体验。 网络异常,图片无法显示 ||网络异常 当然,不可否认的是,"由于盗版软件缺乏开发、维护和升级成本,销售价格远低于正版软件。再加上很多普通人并不需要使用正版软件的复杂功能,版权观念较淡,还是有大量的创意设计人员会选择盗版软件"。 但事实上,当所有的软件都不再是单一的软件,而是变成一种服务时,单机版盗版的存在就逐渐成为鸡肋。因为有太多的服务让你即使是所谓的 "完美破解",也无法享受,Adobe Cloud 就是一个很好的例子,所谓的完美破解,你只能使用 "Adobe "的一半,对于更精彩的 "云",只能望云兴叹。更何况,越来越多的设计工具从免费走向付费,越来越多的设计师和企业已经接受了付费使用的模式。 其次,对于互联网时代的企业数字化转型而言,数字化合规至关重要。21年来,使用盗版PS和未经授权的方正字体被指侵权的事情闹得沸沸扬扬,虽然新闻真假难辨,但也给使用盗版工具的用户敲响了警钟。 付费使用正版工具,可以更放心地进行设计,不用担心版权风险!
-
搞定!让你轻松掌握JS自动复制内容的多种方法
-
搞定Pandas!让你轻松掌握列排序的多种方式