你的位置:首页 > Java教程

[Java教程]关于Javascript中的复制


在做项目时有一个需求,是需要复制内容到剪切板,因为有众多浏览器,所以要兼容性很重要

1、最简单的copy,只能在IE下使用

使用clipboardData方法

<script language="javascript">  function copy(){    window.clipboardData.setData("text",document.getElementById("name").value);    alert("The text is on the clipboard, try to paste it!");  }</script> 

2、跨浏览器的,但是Firefox无法复制

<head>  <script type="text/javascript">    function CopyToClipboard () {      var input = document.getElementById ("toClipboard");      var textToClipboard = input.value;            var success = true;      if (window.clipboardData) { // Internet Explorer        window.clipboardData.setData ("Text", textToClipboard);      }      else {          // create a temporary element for the execCommand method        var forExecElement = CreateElementForExecCommand (textToClipboard);            /* Select the contents of the element               (the execCommand for 'copy' method works on the selection) */        SelectContent (forExecElement);        var supported = true;          // UniversalXPConnect privilege is required for clipboard access in Firefox        try {          if (window.netscape && netscape.security) {            netscape.security.PrivilegeManager.enablePrivilege ("UniversalXPConnect");          }            // Copy the selected content to the clipboard            // Works in Firefox and in Safari before version 5          success = document.execCommand ("copy", false, null);        }        catch (e) {          success = false;        }                  // remove the temporary element        document.body.removeChild (forExecElement);      }      if (success) {        alert ("The text is on the clipboard, try to paste it!");      }      else {        alert ("Your browser doesn't allow clipboard access!");      }    }    function CreateElementForExecCommand (textToClipboard) {      var forExecElement = document.createElement ("div");        // place outside the visible area      forExecElement.style.position = "absolute";      forExecElement.style.left = "-10000px";      forExecElement.style.top = "-10000px";        // write the necessary text into the element and append to the document      forExecElement.textContent = textToClipboard;      document.body.appendChild (forExecElement);        // the contentEditable mode is necessary for the execCommand method in Firefox      forExecElement.contentEditable = true;      return forExecElement;    }    function SelectContent (element) {        // first create a range      var rangeToSelect = document.createRange ();      rangeToSelect.selectNodeContents (element);        // select the contents      var selection = window.getSelection ();      selection.removeAllRanges ();      selection.addRange (rangeToSelect);    }  </script></head><body>  <input id="toClipboard" value="text to clipboard"/>  <button onclick='CopyToClipboard ()'>Copy text to clipboard</button></body>

测试后,Firefox访问失败

3、万能的flash

不要重复造轮子了,有一个使用广泛的类库ZeroClipboard

Zero Clipboard 的实现原理 

Zero Clipboard 利用 Flash 进行复制,之前有 Clipboard Copy 解决方案,其利用的是一个隐藏的 Flash。但最新的 Flash Player 10 只允许在 Flash 上进行操作才能启动剪贴板。所以 Zero Clipboard 对此进行了改进,用了一个透明的 Flash ,让其漂浮在按钮之上,这样其实点击的不是按钮而是 Flash ,也就可以使用 Flash 的复制功能了。 

  • 创建一个透明的flash

  • 将这个flash浮在按钮上层

  • 确定要复制的文本是什么

  • 监听这个透明flash的鼠标点击事件

  • 该flash被点击之后,完成剪切板处理

对于这几件事,ZeroClipboard分别提供了不同的api,来完成整个需求


如何使用 Zero Clipboard 

完整代码直接下载即可

git clone https://github.com/chenpingzhao/easycopy.git

关于ZeroClipboard

var ZeroClipboard = {  version: "1.0.7",  clients: {},  moviePath: "zeroclipboard.swf",  nextId: 1,  $: function(A) {    if (typeof(A) == "string") {      A = document.getElementById(A)    }    if (!A.addClass) {      A.hide = function() {        this.style.display = "none"      };      A.show = function() {        this.style.display = ""      };      A.addClass = function(B) {        this.removeClass(B);        this.className += " " + B      };      A.removeClass = function(D) {        var E = this.className.split(/\s+/);        var B = -1;        for (var C = 0; C < E.length; C++) {          if (E[C] == D) {            B = C;            C = E.length          }        }        if (B > -1) {          E.splice(B, 1);          this.className = E.join(" ")        }        return this      };      A.hasClass = function(B) {        return !!this.className.match(new RegExp("\\s*" + B + "\\s*"))      }    }    return A  },  setMoviePath: function(A) {    this.moviePath = A  },  dispatch: function(D, B, C) {    var A = this.clients[D];    if (A) {      A.receiveEvent(B, C)    }  },  register: function(B, A) {    this.clients[B] = A  },  getDOMObjectPosition: function(C, A) {    var B = {      left: 0,      top: 0,      width: C.width ? C.width : C.offsetWidth,      height: C.height ? C.height : C.offsetHeight    };    while (C && (C != A)) {      B.left += C.offsetLeft;      B.top += C.offsetTop;      C = C.offsetParent    }    return B  },  Client: function(A) {    this.handlers = {};    this.id = ZeroClipboard.nextId++;    this.movieId = "ZeroClipboardMovie_" + this.id;    ZeroClipboard.register(this.id, this);    if (A) {      this.glue(A)    }  }};ZeroClipboard.Client.prototype = {  id: 0,  ready: false,  movie: null,  clipText: "",  handCursorEnabled: true,  cssEffects: true,  handlers: null,  //我们可以通过下面这个api,将flash和按钮重叠,且浮在按钮之上  glue: function(D, B, E) {    this.domElement = ZeroClipboard.$(D);    var F = 99;    if (this.domElement.style.zIndex) {      F = parseInt(this.domElement.style.zIndex, 10) + 1    }    if (typeof(B) == "string") {      B = ZeroClipboard.$(B)    } else {      if (typeof(B) == "undefined") {        B = document.getElementsByTagName("body")[0]      }    }    var C = ZeroClipboard.getDOMObjectPosition(this.domElement, B);    this.div = document.createElement("div");    var A = this.div.style;    A.position = "absolute";    A.left = "" + C.left + "px";    A.top = "" + C.top + "px";    A.width = "" + C.width + "px";    A.height = "" + C.height + "px";    A.zIndex = F;    if (typeof(E) == "object") {      for (addedStyle in E) {        A[addedStyle] = E[addedStyle]      }    }    B.appendChild(this.div);    this.div.innerHTML = this.getHTML(C.width, C.height)  },  /*IE 的 Flash JavaScript 通信接口上有一个 bug 。  你必须插入一个 object 标签到一个已存在的 DOM 元素中。并且在写入 innerHTML 之前请确保该元素已经 appendChild 方法插入到 DOM 中*/  getHTML: function(D, A) {    var C = "";    var B = "id=" + this.id + "&width=" + D + "&height=" + A;    if (navigator.userAgent.match(/MSIE/)) {      var E = location.href.match(/^https/i) ? "https://" : "http://";      C += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="' + E + 'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="' + D + '" height="' + A + '" id="' + this.movieId + '" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="' + ZeroClipboard.moviePath + '" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="' + B + '"/><param name="wmode" value="transparent"/></object>'    } else {      C += '<embed id="' + this.movieId + '" src="' + ZeroClipboard.moviePath + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="' + D + '" height="' + A + '" name="' + this.movieId + '" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + B + '" wmode="transparent" />'    }    return C  },  hide: function() {    if (this.div) {      this.div.style.left = "-2000px"    }  },  show: function() {    this.reposition()  },  destroy: function() {    if (this.domElement && this.div) {      this.hide();      this.div.innerHTML = "";      var A = document.getElementsByTagName("body")[0];      try {        A.removeChild(this.div)      } catch (B) {}      this.domElement = null;      this.div = null    }  },  /* 因为按钮上漂浮有一个 Flash 按钮,所以当页面大小发生变化时,Flash 按钮可能会错位,就点不着了   Zero Clipboard 提供了一个 reposition() 方法,可以重新计算 Flash 按钮的位置。我们可以将它绑定到 resize 事件上   bind(window, "resize", function(){ clip.reposition(); });     function bind(obj, type, fn) {    if (obj.attachEvent) {      obj['e' + type + fn] = fn;      obj[type + fn] = function() {        obj['e' + type + fn](window.event);      }      obj.attachEvent('on' + type, obj[type + fn]);    } else      obj.addEventListener(type, fn, false);  }*/  reposition: function(C) {    if (C) {      this.domElement = ZeroClipboard.$(C);      if (!this.domElement) {        this.hide()      }    }    if (this.domElement && this.div) {      var B = ZeroClipboard.getDOMObjectPosition(this.domElement);      var A = this.div.style;      A.left = "" + B.left + "px";      A.top = "" + B.top + "px"    }  },  setText: function(A) {    this.clipText = A;    if (this.ready) {      this.movie.setText(A)    }  },  addEventListener: function(A, B) {    A = A.toString().toLowerCase().replace(/^on/, "");    if (!this.handlers[A]) {      this.handlers[A] = []    }    this.handlers[A].push(B)  },  setHandCursor: function(A) {    this.handCursorEnabled = A;    if (this.ready) {      this.movie.setHandCursor(A)    }  },  /*鼠标移到按钮上或点击时,由于有 Flash 按钮的遮挡,所以像 css ":hover", ":active" 等伪类可能会失效。  setCSSEffects() 方法就是解决这个问题。首先我们需要将伪类改成类   copy - botton: hover {    border - color: #FF6633;  }  可以改成下面的 ":hover" 改成 ".hover"     copy - botton.hover {    border - color: #FF6633;  }  我们可以调用 clip.setCSSEffects( true ); 这样 Zero Clipboard 会自动为我们处理:将类 .hover 当成伪类 :hover*/  setCSSEffects: function(A) {    this.cssEffects = !! A  },  /*Zero Clipboard 提供了一些事件,你可以自定义函数处理这些事件。  Zero Clipboard 事件处理函数为 addEventListener(); 例如当 Flash 完全载入后会触发一个事件 "load"   clip.addEventListener( "load", function(client) {     alert("Flash 加载完毕!");   });*/  receiveEvent: function(D, E) {    D = D.toString().toLowerCase().replace(/^on/, "");    switch (D) {      case "load":        this.movie = document.getElementById(this.movieId);        if (!this.movie) {          var C = this;          setTimeout(function() {            C.receiveEvent("load", null)          }, 1);          return        }        if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {          var C = this;          setTimeout(function() {            C.receiveEvent("load", null)          }, 100);          this.ready = true;          return        }        this.ready = true;        this.movie.setText(this.clipText);        this.movie.setHandCursor(this.handCursorEnabled);        break;      case "mouseover":        if (this.domElement && this.cssEffects) {          this.domElement.addClass("hover");          if (this.recoverActive) {            this.domElement.addClass("active")          }        }        break;      case "mouseout":        if (this.domElement && this.cssEffects) {          this.recoverActive = false;          if (this.domElement.hasClass("active")) {            this.domElement.removeClass("active");            this.recoverActive = true          }          this.domElement.removeClass("hover")        }        break;      case "mousedown":        if (this.domElement && this.cssEffects) {          this.domElement.addClass("active")        }        break;      case "mouseup":        if (this.domElement && this.cssEffects) {          this.domElement.removeClass("active");          this.recoverActive = false        }        break    }    if (this.handlers[D]) {      for (var B = 0, A = this.handlers[D].length; B < A; B++) {        var F = this.handlers[D][B];        if (typeof(F) == "function") {          F(this, E)        } else {          if ((typeof(F) == "object") && (F.length == 2)) {            F[0][F[1]](this, E)          } else {            if (typeof(F) == "string") {              window[F](this, E)            }          }        }      }    }  }};

  

 参考文章

http://www.jb51.net/article/22403.htm

http://www.cnblogs.com/yangjunhua/archive/2012/09/10/2678817.html

http://jiongks.name/blog/zeroclipboard-intro/