1. 程式人生 > >ZeroClipboard2跨瀏覽器複製貼上

ZeroClipboard2跨瀏覽器複製貼上

摘要:我們平時常用到的複製貼上功能,在瀏覽器端,要想使用一個按鈕來實現,使用原生js程式碼來實現,是困難的,幸好ZeroClipboard的出現,解決了這一尷尬的問題。

ZeroClipboard2簡介

在前端頁面設計時,按鈕常常伴隨著資料的提交或重置出現。然而某一次,需求是點選按鈕,將後臺展示在頁面的特定內容複製到剪下板,這樣使用者就省去了選中文字並按Crtl+C的操作。這使我有機會接觸並使用到了一款好的工具:ZeroClipboard2。
ZeroClipboard2實現原理很簡單:利用透明的 flash 覆蓋在複製按鈕上,點選 flash,將複製內容傳入到 flash 中,再通過 flash 把傳入的內容寫到剪貼簿上。
ZeroClipboard2使用方法也簡單粗暴:把 flash 和 js 放到同一路徑下,然後引用 js 即可。

ZeroClipboard2簡單應用

先看一個例子,瞭解一下最簡單的ZeroClipboard2使用:
可能用到的工具
- ZeroClipboard2.2.0
- Eclipse 4.5
- Tomcat 7
- JQuery 1.7.2
- ExtJs

如下 clip.html

<!DOCTYPE HTML>
<html >
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    <title>ZeroClipboard 測試</title
>
</head> <body> 文字: <input type="text" name="txt" id="content" value="要複製的內容" /> <button id="copy" data-clipboard-target="content">copy</button> <br /><br /> 貼上: <input type="text"> </body> </html> <script type="text/javascript"
src="js/ZeroClipboard.js">
</script> <script type="text/javascript" > window.onload = function(){ var clip = new ZeroClipboard(document.getElementById("copy")); }; </script>

專案的骨架:
這裡寫圖片描述
使用時需要引入ZeroClipboard2所需要的檔案ZeroClipboard.js和ZeroClipboard.swf檔案,建議將其放入一個目錄下。
程式碼中用到的data-clipboard-target屬性是為了指定要複製內容的id,ZeroClipboard 將依次嘗試通過該元素的value、textContent、innerText屬性來獲取文字資料,將content的資料繫結到id為copy的button上。
由於 Flash 本地沙箱的安全限制,以上程式碼如果是在本地HTML檔案中被瀏覽器直接開啟,將無法正常工作。我是用Tomcat執行的,而且如果是Eclipse預設方式開啟的頁面,也是不能工作的,需要在本地瀏覽器中開啟。

在chrom中開啟:
這裡寫圖片描述

點選copy,在貼上欄中Ctrl+v,即可看到效果:
這裡寫圖片描述

ZeroClipboard2與JQuery :

實際使用時,我們很少將js程式碼與html程式碼放在一起,而是引入js檔案,可能還會用到JQuery。
改進 clip.html

<!DOCTYPE HTML>
<html >
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    <title>ZeroClipboard 測試</title>
</head>
<body>
    文字:
    <input type="text" name="txt" id="content" value="要複製的內容" />
    <button id="copy" data-clipboard-target="content">copy</button>
    <br /><br />
    貼上:
    <input type="text">
</body>
</html>
<script type="text/javascript" src="js/ZeroClipboard.js"></script>
<script type="text/javascript" src="js/jquery-1.7.2.js"></script>
<script type="text/javascript" src="js/demo.js"></script>

引入的demo.js

$(document).ready(function(){
    var clip = new ZeroClipboard($("#copy"));
});

專案的骨架:
這裡寫圖片描述

ZeroClipboard2與ExtJs:

在生產環境中,我們使用的是ExtJs。在這個過程中,最難控制的就是何時初始化ZeroClipboard,因為ExtJs的按鈕是在後期生成的,我不能很容易的新增諸如data-clipboard-target屬性的方法告訴ZeroClipboard去複製什麼內容,也沒有一個很清楚的位置去寫new ZeroClipboard()這樣的邏輯,那麼該如何處理呢?

  • ExtJs 應該在適當的位置初始化ZeroClipboard
    在使用ExtJS建立button時,常常使用如下方法:
Ext.onReady(function(){   
var buttonName = new Ext.Button({
                 id:"buttonName",
                 renderTo:Ext.getBody(),  
                 minWidth:100,   
                 handler:function(){   
                     Ext.MessageBox.show({   
                       title: '提示' ,  
                       msg: '你點選了我!' ,  
                       buttons: Ext.MessageBox.OK ,
                       fn: function(){}
                     });  
                  }  
               });   
});  

那麼在初始化button時,就應該考慮初始化ZeroClipboard。你可以在瀏覽器的console中檢視初始化是否完成。
- 在頁面載入完成以後,在瀏覽器中應該存在ZeroClipboard物件。
- 使用自帶方法檢視:ZeroClipboard.state()

這裡寫圖片描述
- 如果一切順利,可以看到ZeroClipboard.state().flash.ready的值為true.

  • 使用ZeroClipboard自帶的複製方法
    有時候,我們無法給button設定data-clipboard-target屬性,可以使用ZeroClipboard自帶的複製方法繫結資料。

其中setText()是最簡單且常用的方法

var clip = new ZeroClipboard($("#copy"));
clip.setText($("#content").val());
//可以設定3中格式,帶有格式的內容貼上到不同的程式,顯示對應的效果
clip.setText("複製的內容");
clip.setHtml("<p>複製的內容</p>");
clip.setRichText("{\\rtf1\n{\\b 複製的內容}}");

還有一種通用的設定方法setData()

clip.setData("text/plain", "複製的內容");
clip.seData("text/html", "<p>複製的內容</p>");
clip.setData("application/rtf", "{\\rtf1\n{\\b 複製的內容}}");

ZeroClipboard2第一次複製不生效:

在ZeroClipboard2與ExtJs結合使用時,我發現,每次複製的第一次不生效,需要點選第二下複製按鈕,才能實現複製效果。在琢磨之後發現,我在繫結資料的時候使用的是setText()方法,而該方法設定的資料是一次性的,使用該方法設定複製資料後,只在下一次複製操作時生效。之後即使你點選複製按鈕也不再執行復制,除非你再次呼叫setText()方法。
解決這個問題,我們在button的回撥函式中使用了的事件copy,改用setData()方法:

clip.on("copy", function(e){
    e.clipboardData.setData("text/plain", "複製的文字")
});