clipboard.js

以更现代的方式将文本复制到剪贴板

无需 Flash、不依赖框架,压缩之后只有 3kb 大小。

项目起因

将文本复制到剪贴板应该是件极其容易的事情!不应该写数百 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>

事件

在某些情况下,你可能需要向用户展示一些反馈信息或者捕获用户所复制/剪切的内容。

我们提供了类似 successerror 这类事件以便您监听并实现自己的业务逻辑。

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();

浏览器支持情况

本工具同时依赖 SelectionexecCommand API。第一个依赖项是 所有浏览器都支持的,第二个依赖项支持的浏览器如下列表所示。

好消息是,如果您需要支持较旧的浏览器,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.

Install for Chrome and Firefox.