木匣子

Web/Game/Programming/Life etc.

在 Chrome 中实现复制/粘贴的方法

在v2ex上看到有人讨论使用现代浏览器(如chrome/firefox)访问优酷,希望点击分享按钮复制视频地址时会弹出诸如这样的提示:

v.youku.com 上的网页提示: 您使用的浏览器不支持此复制功能,请使用Ctrl+C或鼠标右键。

想到在 Chrome 中使用 vimium 扩展时确实能很自如地复制链接,那么 vimium 是如何现实的呢。我翻了一下 vimium 由 CoffeeScript 编译后的 javascript 代码,其中有一个闭包专门完成复制与粘贴功能。代码如下:

// Generated by CoffeeScript 1.4.0
(function() {
  var Clipboard, root;

  Clipboard = {
    _createTextArea: function() {
      var textArea;
      textArea = document.createElement("textarea");
      textArea.style.position = "absolute";
      textArea.style.left = "-100%";
      return textArea;
    },
    copy: function(data) {
      var textArea;
      textArea = this._createTextArea();
      textArea.value = data;
      document.body.appendChild(textArea);
      textArea.select();
      **document.execCommand("Copy");**
      return document.body.removeChild(textArea);
    },
    paste: function() {
      var textArea, value;
      textArea = this._createTextArea();
      document.body.appendChild(textArea);
      textArea.focus();
      **document.execCommand("Paste");**
      value = textArea.value;
      document.body.removeChild(textArea);
      return value;
    }
  };

  root = typeof exports !== "undefined" && exports !== null ? exports : window;

  root.Clipboard = Clipboard;

}).call(this);

请注意 document.execCommand("Copy");document.execCommand("Paste"); 这两句。这个闭包通过 _createTextArea() 方法巧妙地构造一个在页面外的文本框(不可以是隐藏的,因为如果隐藏了就无法选择其中的文本了),然后将要复制的内容填到框中,并通过 select() 方法选择文本框中的内容。最后执行 document.execCommand("Copy"); 将内容复制到剪贴板中并销毁文本框。这是一个很妙的方法,但我更关心的是这个函数能否在一般的页面中调用呢? 我把上面这段代码保存到 HTML 中,并在结尾调用以下代码进行测试:

window.Clipboard.copy("hello world");

程序全部执行了,但剪贴板中结果没有出现"hello world"。这表明 google chrome 没有把这个 API 开放给网页开发者。出于安全性考虑,只有在扩展程序中才可以使用,并且要在扩展的 manifest 中请求 “clipboardRead” and “clipboardWrite” 这两项权限。 想想这也挺合理的,谁也不想在浏览网页的时候,剪贴板就被植入广告了——我还真干用这种事——用的是flash,hah。于是有人利用 flash 的这个特性绕过了浏览器的限制,发布了 Zero Clipboard 这个项目用于实现跨浏览器访问剪贴版。项目地址:https://code.google.com/p/zeroclipboard/

如果你真的有这样的需求,就考虑用它吧。当然,这是需要浏览器有 flash player 支持的。