1. 程式人生 > >使用ZeroClipboard 複製指定內容到剪下板

使用ZeroClipboard 複製指定內容到剪下板

有些時候,我們希望讓使用者在網頁上完成某個操作就能自動將指定的內容複製到使用者計算機的剪貼簿中。但是出於安全原因,大多數現代瀏覽器都未提供通用的剪貼簿複製介面(或即便有,也預設被禁用)。只有IE瀏覽器可以通過如下方式來進行復制。

window.clipboardData.setData(“Text”, “這裡是需要複製的文字內容”)
想要實現跨瀏覽器的複製功能,我們就可以使用 ZeroClipboard。

ZeroClipboard 及其原理介紹
ZeroClipboard 是國外大神開發的一個用於剪貼簿複製的 JS 外掛,它是基於 Flash 來實現跨瀏覽器的複製功能的。當我們使用 ZeroClipboard 的時候,它會悄悄隱藏一個小小的 Flash 影片(swf),不會對我們的使用者介面造成影響。我們只需要藉助它實現複製功能就行了。ZeroClipboard 中的 “Zero” 指的就是"不可見,零干擾"。

不過從 Flash 10開始,由於瀏覽器和Flash的安全限制,要求使用者必須在Flash區域上進行真實操作才能操作剪貼簿。於是,ZeroClipboard 的作者想到一個辦法:它將 Flash 做成透明的,以便於我們放在諸如連結、按鈕等需要放置的任何地方。這樣,使用者介面看起來沒有變化,當點選連結或按鈕時,實際上點選是卻是 Flash,從而實現複製操作。

ZeroClipboard 快速入門
使用 ZeroClipboard 的方法非常簡單,我們只需要在頁面中引入它的一個JS檔案並稍作配置(最簡單隻需一行程式碼)即可(實際上還需要引入一個Flash的swf檔案,不過 ZeroClipboard 會自動引入它)。

請參考下面的示例程式碼:

注意:這裡介紹的是目前最新版 ZeroClipboard 2.1.6 的用法,2.x 版本均可參考,但 1.x 的用法與此並不相同!
ZeroClipboard 2.x 原則上不相容IE 6 ~ IE 8等低版本IE瀏覽器,如果需要相容IE 6 ~ IE 8,請使用 1.x 或者 2.0.2 版本(詳情可以參考下方評論中的官方連結),推薦使用 2.0.2 版本。
此外,由於 Flash 本地沙箱的安全限制,以下程式碼如果是在本地HTML檔案中被瀏覽器直接開啟,將無法正常工作。在這裡提供一個資源不錯的CDN庫(http://www.bootcdn.cn/),在這裡可以找到我們想要使用的ZeroClipboard2.0.2版本。以下是bootcdn中ZeroClipboard連結:http://cdn.bootcss.com/zeroclipboard/2.0.2/ZeroClipboard.min.js

這裡是需要複製的內容

以上就是引入並使用 ZeroClipboard 的最簡程式碼。我們為【複製】按鈕指定了data-clipboard-target屬性,其值為將被複制資料的元素id。此時,我們點選【複製】按鈕就可以複製id為content的textarea中的文字資料。你可以點選這裡 執行程式碼

ZeroClipboard 重要事項
關於檔案引入和本地化使用
上面我們引入的JS檔案是 ZeroClipboard 官方提供的 CDN,你可以直接使用。如果你想將其下載到本地伺服器上使用,你可以進入官方網站下載最新版本。然後將dist目錄下的ZeroClipboard.js(或者壓縮版的ZeroClipboard.min.js)和ZeroClipboard.swf這兩個檔案上傳到自己的伺服器即可。

請確保它們被放在同一目錄下,以便於 ZeroClipboard.js 自動載入 ZeroClipboard.swf 檔案。否則你需要在使用前額外配置swf檔案的路徑。

// 在 new ZeroClipboard()之前,需要先配置 ZeroClipboard.swf 檔案的路徑
ZeroClipboard.config( { swfPath: ‘http://YOURSERVER/path/ZeroClipboard.swf’ } );
多個複製載體
如果你希望在頁面中有多個按鈕、連結等元素充當複製資料的載體,你可以以陣列(或類陣列)形式傳入多個元素。以下幾種方式都是可以的:

// 方式一 (生成多個ZeroClipboard物件,適合不同載體複製不同來源的資料)
var clip = new ZeroClipboard( document.getElementById(“copy”) );
var clip2 = new ZeroClipboard( document.getElementById(“copy2”) );

// 方式二 (生成一個ZeroClipboard物件,適合不同載體複製相同來源的資料)
var doms = [ document.getElementById(“copy”), document.getElementById(“copy2”) ];
// var doms = document.getElementsByName(“copy”); // 通過ByName或ByTagName獲取多個元素也是可以的
// var doms = $(".copy"); // 通過jQuery物件也是可以的
// 只要是通過length屬性訪問元素個數、通過數字索引來訪問DOM元素的物件都是可以的
var clip = new ZeroClipboard( doms );
更改複製載體
如果之前你使用【按鈕1】來充當複製載體,現在你想新增【按鈕2】來充當複製載體。你可以呼叫 ZeroClipboard 例項的clip()方法:

var clip = new ZeroClipboard( document.getElementById(“copy”) );
// 新增id為copy2的元素作為複製載體,原來id為copy的元素依然可用
clip.clip( document.getElementById(“copy2”) /* 也可以陣列形式傳入多個 */ );
如果你想要解除安裝指定的複製載體,你可以使用unclip()方法。

// 取消id為copy2的元素上註冊的複製功能
clip.unclip( document.getElementById(“copy2”) /* 也可以陣列形式傳入多個 */ );

// 不指定任何引數,則取消該物件之前在所有元素上註冊的複製功能
clip.clip();
設定用於複製的文字資料
如果指定了data-clipboard-target屬性,ZeroClipboard 將依次嘗試通過該元素的value、textContent、innerText屬性來獲取文字資料(依次判斷是否有上述屬性,並以最靠前的屬性為準)。

當然,ZeroClipboard 也並非只能通過其他元素才能獲得用於複製的文字資料,我們還可以給複製載體自身的data-clipboard-text屬性來設定用於複製的文字資料,之後你還可以通過設定該屬性值(setAttribute())來更改需要複製的文字內容。

此外,我們甚至無需通過元素節點的屬性來設定用於複製的文字資料,我們可以直接使用 ZeroClipboard 物件的setText()方法來設定文字資料。注意,該方法設定的資料是一次性的,使用該方法設定複製資料後,只在下一次複製操作時生效。之後即使你點選複製按鈕也不再執行復制,除非你再次呼叫setText()方法(你可以繫結複製("copy")事件來呼叫該方法,從而實現每次複製操作都設定資料,下面我們會講到)。

clip.setText(“設定用於複製的文字內容”);
資料來源的優先順序問題:如果我們同時為複製載體設定了data-clipboard-text、 data-clipboard-target屬性,並呼叫了setText()方法,那麼 ZeroClipboard 複製資料的優先順序是:setText() > data-clipboard-target > data-clipboard-text。

如果前者沒有文字資料(沒有呼叫、 沒有屬性或者資料為空字串),則以下一個優先順序為準,如果都沒有文字資料,則不復制。

舉例來說,如果同時設定上述三者。第一次複製:先取setText()設定的資料,如果為空字串,則取data-clipboard-target對應元素的資料;如果它也為空字串,則取data-clipboard-text屬性的文字資料;如果它也為空字串,則不復制。注意,由於setText()設定的資料是一次性的,下一次複製將以data-clipboard-target屬性為準(除非再次呼叫setText()方法)。

資料型別
眾所周知,剪貼簿中的資料是有型別的,每一種型別都可以有自己的資料。我們複製的資料可以有多種型別,當我們貼上的時候,會貼上當前程式可接受型別的資料。

ZeroClipboard也支援設定多種型別的剪貼簿資料。它為我們提供了setText()、setHtml、setRichText()方法分別用於設定純文字資料、HTML內容、富文字內容。

// 可同時設定,貼上時根據接收程式的不同,而粘貼出不同的內容
clip.setText(“CodePlayer”);
clip.setHtml(“CodePlayer”);
clip.setRichText("{\rtf1\ansi\n{\b CodePlayer}}");
此外,ZeroClipboard還提供了一個通用的設定方法setData(),用於設定各種型別的資料。

// 可同時設定,貼上時根據接收程式的不同,而粘貼出不同的內容
clip.setData(“text/plain”, “CodePlayer”);
clip.seData(“text/html”, “CodePlayer”);
clip.setData(“application/rtf”, “{\rtf1\ansi\n{\b CodePlayer}}”);
事件處理
ZeroClipboard 還為我們提供了事件支援,以便於處理ZeroClipboard觸發的各種事件。ZeroClipboard支援的事件有"ready"、 “beforecopy”、 “copy”、 “aftercopy”、 “destroy”、 “error”。

我們可以通過on()方法來註冊事件處理函式。

// 當Flash SWF檔案載入完成並準備就緒時觸發ready事件
clip.on(“ready”, function(){ alert(“載入完成!”); });

// 當觸發copy事件時,設定用於複製的文字資料
clip.on(“copy”, function(e){
e.clipboardData.setData(“text/plain”, “這裡是用於複製的純文字資料”)
});
此外,off()方法用來取消註冊的事件處理函式,emit()方法用來手動觸發事件。其用法與jQuery的on()、 off()、 trigger()方法非常相似。

此外,如果你有多個ZeroClipboard物件,你想為它們都註冊事件處理函式。你可以使用全域性物件ZeroClipboard的靜態方法ZeroClipboard.on()、 ZeroClipboard.off()、ZeroClipboard.emit()來全域性性地設定事件。全域性事件將對每個物件都生效。

關於事件處理的詳細用法,請參考ZeroClipboard事件及其屬性細節。