项目起因
将文本复制到剪贴板应该是件极其容易的事情!不应该写数百 KB 的代码和一大堆的配置!最重要的是,无需依赖 Flash 或者任何第三方框架!
这就是 clipboard.js 存在的意义。
安装
通过 npm 安装:
npm install clipboard --save
如果你对软件包包管理工具(package management)不感冒,还可以直接 下载 ZIP 压缩包。
设置
首先,将 dist
目录下面的 JavaScript 文件引入到页面,或者使用第三方 CDN 提供的文件加速服务。
<script src="dist/clipboard.min.js"></script>
接下来,你需要通过 传递 DOM 选择器、HTML 元素 或 HTML 元素列表 的方式对其进行初始化。
new ClipboardJS('.btn');
在 Clipboard.js 的内部,我们需要获取与您所提供的选择器相匹配的所有元素,并为每个元素添加一个事件监听器。如果有数百个元素的话,你猜会发生什么?这一操作会消耗大量内存。
因此,我们使用 事件委派(event delegation) 的方式将多个事件监听器替换为一个事件监听器。毕竟,#性能攸关。
用法
我们正在经历 声明式语法的流行阶段,这也是我们为什么决定利用 HTML5 data 属性 这一功能来提高使用的便利性。
从其他元素复制文本
一个非常常见的使用场景是从另一个元素复制内容。你可以通过在触发元素(trigger element)上添加 data-clipboard-target
属性来达成这一功能。
你为 data-clipboard-target
属性所设置的值必须是另一个元素的选择器。
<!-- Target -->
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo">
<img src="assets/clippy.svg" alt="Copy to clipboard">
</button>
从另一个元素剪切文本
此外,你还可以通过设置 data-clipboard-action
属性来指定是 copy(复制)
还是 cut(剪切)
内容。
如果你省略此属性,默认操作是 copy(复制)
内容。
<!-- Target -->
<textarea id="bar">Mussum ipsum cacilds...</textarea>
<!-- Trigger -->
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
Cut to clipboard
</button>
正如你所预料的, cut(剪切)
操作只对 <input>
或 <textarea>
元素起作用。
从属性复制文本
其实,你所要复制的内容甚至都不需要来自另一个元素。你可以为触发元素(trigger element)设置一个 data-clipboard-text
属性来指定要复制的内容。
<!-- Trigger -->
<button class="btn" data-clipboard-text="Just because you can doesn't mean you should — clipboard.js">
Copy to clipboard
</button>
事件
在某些情况下,你可能需要向用户展示一些反馈信息或者捕获用户所复制/剪切的内容。
我们提供了类似 success
和 error
这类事件以便您监听并实现自己的业务逻辑。
var clipboard = new ClipboardJS('.btn');
clipboard.on('success', function(e) {
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
请打开浏览器的调试工具的控制台(console)窗口观看实际效果 :)
提示条(Tooltips)
每个应用程序都有不同的设计理念,这也是为什么 clipboard.js 不内嵌任何 CSS 或提示条(tooltip)解决方案的原因。
您在本网站上看到的提示条(tooltips)是使用 GitHub 的 Primer CSS 库 实现的。如果您希望获得类似的外观和体验,可以参考本网站的源码。
高级用法
如果你不希望修改 HTML,还有一个相当方便的 API 供你使用。你所要做的知识声明一个函数,实现你的功能,然后返回一个值。
例如,如果你希望动态地设置 target
,你就需要返回一个 HTML Node 元素。
new ClipboardJS('.btn', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
如果你希望动态地设置 text
,则需要返回一个字符串。
new ClipboardJS('.btn', {
text: function(trigger) {
return trigger.getAttribute('aria-label');
}
});
如果需要配合其它会改变焦点的工具库(例如 Bootstrap 的模态框)一起使用的话,你需要将 container
参数设置为获得焦点的元素。
new ClipboardJS('.btn', {
container: document.getElementById('modal')
});
此外,如果你要在单页应用程序(single page apps)中使用 Clipboard.js 的话,则需要更精确地管理 DOM 的生命周期。以下代码展示了如何清理 Clipboard.js 所创建的事件和对象。
var clipboard = new ClipboardJS('.btn');
clipboard.destroy();
浏览器支持情况
本工具同时依赖 Selection 和 execCommand API。第一个依赖项是 所有浏览器都支持的,第二个依赖项支持的浏览器如下列表所示。
-
Chrome 42+
-
Edge 12+
-
Firefox 41+
-
IE 9+
-
Opera 29+
-
Safari 10+
好消息是,如果您需要支持较旧的浏览器,clipboard.js 能够提供优雅的降级。您所要做的就是在触发 success
事件时显示一个写有 已复制!
字样的提示条(tooltip),在触发 error
事件时显示一个写有 请按 Ctrl+C 键复制选中的内容
字样的提示条(因为此时文本已经被设置为选中状态了,用户只需要按 Ctrl+C 键就能复制内容了)。
你还可以通过执行 ClipboardJS.isSupported()
函数来检查 clipboard.js 是否支持当前的浏览器,这样您就可以隐藏复制/剪切按钮了。
Bonus
A browser extension that adds a "copy to clipboard" button to every code block on GitHub, MDN, Gist, StackOverflow, StackExchange, npm, and even Medium.