跨浏览器复制神器 ZeroClipboard 2.x快速入门详解

有些时候,我们希望让用户在网页上完成某个操作就能自动将指定的内容复制到用户计算机的剪贴板中。但是出于安全原因,大多数现代浏览器都未提供通用的剪贴板复制接口(或即便有,也默认被禁用)。只有IE浏览器可以通过如下方式来进行复制。

window.clipboardData.setData("Text", "这里是需要复制的文本内容")
想要实现跨浏览器的复制功能,我们就可以使用 ZeroClipboard。

ZeroClipboard 及其原理介绍

ZeroClipboard 是国外大神开发的一个用于剪贴板复制的 JS 插件,它是基于 Flash 来实现跨浏览器的复制功能的。当我们使用 ZeroClipboard 的时候,它会悄悄隐藏一个小小的 Flash 影片(swf),不会对我们的用户界面造成影响。我们只需要借助它实现复制功能就行了。ZeroClipboard 中的 "Zero" 指的就是"不可见,零干扰"。

不过从 Flash 10开始,由于浏览器和Flash的安全限制,要求用户必须在Flash区域上进行真实操作才能操作剪贴板。于是,ZeroClipboard 的作者想到一个办法:它将 Flash 做成透明的,以便于我们放在诸如链接、按钮等需要放置的任何地方。这样,用户界面看起来没有变化,当点击链接或按钮时,实际上点击是却是 Flash,从而实现复制操作。

ZeroClipboard 快速入门

使用 ZeroClipboard 的方法非常简单,我们只需要在页面中引入它的一个JS文件并稍作配置(最简单只需一行代码)即可(实际上还需要引入一个Flash的swf文件,不过 ZeroClipboard 会自动引入它)。

请参考下面的示例代码:
注意:这里介绍的是目前最新版 ZeroClipboard 2.1.6 的用法,2.x 版本均可参考,但 1.x 的用法与此并不相同!ZeroClipboard 2.x 原则上不兼容IE 6 ~ IE 8等低版本IE浏览器,如果需要兼容IE 6 ~ IE 8,请使用 1.x 或者 2.0.2 版本(详情可以参考下方评论中的官方链接),推荐使用 2.0.2 版本。此外,由于 Flash 本地沙箱的安全限制,以下代码如果是在本地HTML文件中被浏览器直接打开,将无法正常工作。

<!-- 这里是HTML代码部分 -->
<textarea id="content" rows="10" cols="60">这里是需要复制的内容</textarea>
<input id="copy" type="button" data-clipboard-target="content" value="复制">
<!-- 这里是JS代码部分 -->
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/2.1.6/ZeroClipboard.min.js" ></script>
<script type="text/javascript">
// 将【复制】按钮充当复制数据的元素载体
var clip = new ZeroClipboard( document.getElementById("copy") );</script>

以上就是引入并使用 ZeroClipboard 的最简代码。我们为【复制】按钮指定了data-clipboard-target
属性,其值为将被复制数据的元素id。此时,我们点击【复制】按钮就可以复制id为content的textarea中的文本数据。你可以点击这里 运行代码

ZeroClipboard 重要事项

关于文件引入和本地化使用

上面我们引入的JS文件是 ZeroClipboard 官方提供的 CDN,你可以直接使用。如果你想将其下载到本地服务器上使用,你可以进入官方网站下载最新版本。然后将dist目录下的ZeroClipboard.js
(或者压缩版的ZeroClipboard.min.js)和ZeroClipboard.swf
这两个文件上传到自己的服务器即可。
请确保它们被放在同一目录下,以便于 ZeroClipboard.js 自动加载 ZeroClipboard.swf 文件。否则你需要在使用前额外配置swf文件的路径。

// 在 new ZeroClipboard()之前,需要先配置 ZeroClipboard.swf 文件的路径
ZeroClipboard.config( { swfPath: 'http://YOURSERVER/path/ZeroClipboard.swf' } );

多个复制载体

如果你希望在页面中有多个按钮、链接等元素充当复制数据的载体,你可以以数组(或类数组)形式传入多个元素。以下几种方式都是可以的:

// 方式一 (生成多个ZeroClipboard对象,适合不同载体复制不同来源的数据)
var clip = new ZeroClipboard( document.getElementById("copy") );
var clip2 = new ZeroClipboard( document.getElementById("copy2") );
// 方式二 (生成一个ZeroClipboard对象,适合不同载体复制相同来源的数据)
var doms = [ document.getElementById("copy"), 
document.getElementById("copy2") ];
// var doms = document.getElementsByName("copy"); 
// 通过ByName或ByTagName获取多个元素也是可以的
// var doms = $(".copy");
// 通过jQuery对象也是可以的
// 只要是通过length属性访问元素个数、通过数字索引来访问DOM元素的对象都是可以的var clip = new ZeroClipboard( doms );

更改复制载体

如果之前你使用【按钮1】来充当复制载体,现在你想添加【按钮2】来充当复制载体。你可以调用 ZeroClipboard 实例的clip()
方法:

var clip = new ZeroClipboard( document.getElementById("copy") );
// 添加id为copy2的元素作为复制载体,原来id为copy的元素依然可用clip.clip( document.getElementById("copy2")
 /* 也可以数组形式传入多个 */  );
如果你想要卸载指定的复制载体,你可以使用unclip()

方法。

// 取消id为copy2的元素上注册的复制功能
clip.unclip( document.getElementById("copy2") /* 也可以数组形式传入多个 */  );
// 不指定任何参数,则取消该对象之前在所有元素上注册的复制功能clip.clip();

设置用于复制的文本数据
如果指定了data-clipboard-target
属性,ZeroClipboard 将依次尝试通过该元素的valuetextContentinnerText属性来获取文本数据(依次判断是否有上述属性,并以最靠前的属性为准)。

当然,ZeroClipboard 也并非只能通过其他元素才能获得用于复制的文本数据,我们还可以给复制载体自身的data-clipboard-text
属性来设置用于复制的文本数据,之后你还可以通过设置该属性值(setAttribute())来更改需要复制的文本内容。

<input id="copy" type="button" data-clipboard-text="这里是用于复制的内容,value="复制">

此外,我们甚至无需通过元素节点的属性来设置用于复制的文本数据,我们可以直接使用 ZeroClipboard 对象的setText()

方法来设置文本数据。注意,该方法设置的数据是一次性的,使用该方法设置复制数据后,只在下一次复制操作时生效。之后即使你点击复制按钮也不再执行复制,除非你再次调用setText()

方法(你可以绑定复制("copy")事件来调用该方法,从而实现每次复制操作都设置数据,下面我们会讲到)。
clip.setText("设置用于复制的文本内容");
数据来源的优先级问题:如果我们同时为复制载体设置了data-clipboard-text
、 data-clipboard-target
属性,并调用了setText()
方法,那么 ZeroClipboard 复制数据的优先级是:setText() > data-clipboard-target > data-clipboard-text
如果前者没有文本数据(没有调用、 没有属性或者数据为空字符串),则以下一个优先级为准,如果都没有文本数据,则不复制。
举例来说,如果同时设置上述三者。第一次复制:先取setText()
设置的数据,如果为空字符串,则取data-clipboard-target
对应元素的数据;如果它也为空字符串,则取data-clipboard-text
属性的文本数据;如果它也为空字符串,则不复制。注意,由于setText()
设置的数据是一次性的,下一次复制将以data-clipboard-target
属性为准(除非再次调用setText()
方法)。

数据类型

众所周知,剪贴板中的数据是有类型的,每一种类型都可以有自己的数据。我们复制的数据可以有多种类型,当我们粘贴的时候,会粘贴当前程序可接受类型的数据。
ZeroClipboard也支持设置多种类型的剪贴板数据。它为我们提供了setText()、setHtml、setRichText()方法分别用于设置纯文本数据、HTML内容、富文本内容。
// 可同时设置,粘贴时根据接收程序的不同,而粘贴出不同的内容clip.setText("CodePlayer");clip.setHtml("<strong>CodePlayer</strong>");clip.setRichText("{\rtf1\ansi\n{\b CodePlayer}}");
此外,ZeroClipboard还提供了一个通用的设置方法setData()
,用于设置各种类型的数据。
// 可同时设置,粘贴时根据接收程序的不同,而粘贴出不同的内容clip.setData("text/plain", "CodePlayer");clip.seData("text/html", "<strong>CodePlayer</strong>");clip.setData("application/rtf", "{\rtf1\ansi\n{\b CodePlayer}}");

事件处理

ZeroClipboard 还为我们提供了事件支持,以便于处理ZeroClipboard触发的各种事件。ZeroClipboard支持的事件有"ready"、 "beforecopy"、 "copy"、 "aftercopy"、 "destroy"、 "error"。
我们可以通过on()
方法来注册事件处理函数。
// 当Flash SWF文件加载完成并准备就绪时触发ready事件clip.on("ready", function(){ alert("加载完成!"); });// 当触发copy事件时,设置用于复制的文本数据clip.on("copy", function(e){ e.clipboardData.setData("text/plain", "这里是用于复制的纯文本数据")});
此外,off()
方法用来取消注册的事件处理函数,emit()
方法用来手动触发事件。其用法与jQuery的on()、 off()、 trigger()方法非常相似。
此外,如果你有多个ZeroClipboard对象,你想为它们都注册事件处理函数。你可以使用全局对象ZeroClipboard的静态方法ZeroClipboard.on()
、 ZeroClipboard.off()
、 ZeroClipboard.emit()
来全局性地设置事件。全局事件将对每个对象都生效。
关于事件处理的详细用法,请参考ZeroClipboard事件及其属性细节

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,358评论 0 17
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,869评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 一只狐狸失足掉到了很深的井里,不论他如何挣扎仍没法爬上去,只好待在那里。一只羊觉得口渴极了,正好来到井边。他看见狐...
    虚怀若谷8阅读 600评论 0 0
  • (一) 孤窗照远影, 空寂宛如烟, 我心无所依, 满目皆怅然! (二) 一季秋风起, 细雨恁凄凉, 落英留情寄, ...
    古城苍狼阅读 297评论 0 6