Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

不依赖Flash,实现剪贴板复制(转) #143

Open
mishe opened this issue Sep 20, 2016 · 2 comments
Open

不依赖Flash,实现剪贴板复制(转) #143

mishe opened this issue Sep 20, 2016 · 2 comments

Comments

@mishe
Copy link
Owner

mishe commented Sep 20, 2016

不依赖Flash,实现剪贴板复制

本文转载自:众成翻译
译者:奈末
链接:http://www.zcfy.cc/article/806
原文:https://hacks.mozilla.org/2015/09/flash-free-clipboard-for-the-web/

    推动Web平台进步,促使Web支持更多新设备的努力尝试从未停止,其中一项便是减少Web对Flash的依赖。作为这项工作的一部分,我们正在为全Web平台标准化并实现一些有效的特性,虽然当前这些特性只能依赖Flash。

    很多站点仍未抛弃Flash的原因之一,是复制和粘贴这两个剪贴板API。Flash提供一个API,能够在点击按钮时动态复制文本到用户的剪贴板。它备用来实现一些便利的功能,比如说GitHub的“copy to clipboard”(复制到剪贴板)按钮。同时,在开发类似文本编辑器UI的场景里它也很有价值:与其让用户使用键盘快捷键或者右键菜单,不如一键复制来得好。

    但是,Web APIs尚未提供通过JavaScript复制文本到剪贴板的功能。这也是为什么禁用Flash访问GitHub时,一个灰色丑陋的区块取代了原本的复制按钮。令人庆幸的是,我们已经有了一个办法。HTML Editing APIs提供了document.execCommand作为执行一些文本编辑命令的入口。之前网页环境下禁用了复制copy和剪切cut两个名令,但是从Firefox 41开始,用户触发的回调JavaScript已经可以使用这两个命令了。


使用 ` execCommand ("cut"/"copy") `


    execCommand("cut"/"copy") API只能在用户触发的回调里使用,比如说一次click事件。如果在其他环境下尝试调用,execCommand将会返回false,表征该命令执行失败。运行execCommand("copy")会将当前选中的内容复制到剪贴板, 现在我们来实现一个基本的一键复制按钮。

// 事件依附的按钮
var button = ...;
// 包含待复制内容的input
var input = ...;

button.addEventListener("click", function(event) {
  event.preventDefault();
  // 选取input元素的内容
  input.select();
  // 将选区内容复制到剪贴板
  document.execCommand("copy");
});

    在Firefox 41及更高版本浏览器中,以上代码会在按钮点击后触发一次复制行为,将input内的文本复制到系统的剪贴板。不过,很可能你需要考虑不兼容的情况:可以使用另一个基于Flash的方法作为备用,例如ZeroClipboard,或者干脆告诉用户他们的浏览器不支持此功能。

    execCommand方法执行失败时会返回false,比如说在用户触发的回调之外尝试调用的时候。但是,在更早版本的Firefox中尝试对cutcopy调用,浏览器会抛出安全性异常SecurityException。所以为了确保捕获所有的异常,要将调用语句包在try-catch里,这样catch到的异常也作为调用失败处理。

// 事件依附的按钮
var button = ...;
// 包含待复制内容的input
var input = ...;

button.addEventListener("click", function(event) {
  event.preventDefault();
  input.select(); // 选取input元素的内容
  var succeeded;
  try {
    // 将选区内容复制到剪贴板
    succeeded = document.execCommand("copy");
  } catch (e) {
    succeeded = false;
  }
  if (succeeded) {
    // 复制成功
  } else {
    // 复制失败 :(
  }
});

cut API的应用同上,把copy替换为cut即可。


特性测试


    HTML Editing APIs提供了document.queryCommandSupported("copy")方法,方便使用者检测某个命令是否被浏览器支持。但是在低于Firefox 41的火狐浏览器里, 纵使实际上开发者无法使用copy命令(尝试调用document.execCommand("copy") 会得到一个SecurityException),此检测方法仍然返回了true。所以在Firefox里最简单的支持document.execCommand("copy")特性检测的办法很可能是这样:页面加载完成则尝试使用copy,检测是否抛出SecurityException

var supported = document.queryCommandSupported("copy");
if (supported) {
  // 检测浏览器是否为比Firefox 41更低的版本
  try {
    document.execCommand("copy");
  } catch (e) {
    supported = false;
  }
}
if (!supported) {
  // 使用备用方法,比如ZeroClipboard,http://zeroclipboard.org/
}

## 其他浏览器的兼容情况

    谷歌Chrome和IE都支持此API。Chrome和Firefox使用相同的限制策略(调用必须在用户触发的事件回调里)。IE则允许随意调用,只在第一次调用时询问用户是否允许操控剪贴板。

更多关于此API的信息或浏览器支持情况,可以查看:

MDN documentation for document.execCommand().

译者附: Can I use execcommand


## 关于作者

Michael Layzell

https://github.com/mystor

More articles by Michael Layzell…

@mishe
Copy link
Owner Author

mishe commented Sep 20, 2016

测试发现pc端可以使用,但手机端无效

@KevinHu-1024
Copy link

貌似当文本域是display: none时,即使里面有内容,复制出来也是空的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants