20 行 JS 程式碼,實現複製到剪貼簿功能

唐耶爾發表於2016-05-12

使用系統提供的剪貼簿是一項基本的IT技能。作為一個開發者,相信你已經知道使用 Ctrl/Cmd+A, Ctrl/Cmd+C 以及 Ctrl/Cmd+V 組合鍵就能快捷地進行選中、複製、貼上。

但對於普通使用者來說就沒那麼容易了。即使使用者知道剪貼簿的存在,視力再好、反應再快的使用者也很難選中他們想要的文字。接下來,如果使用者沒有掌握快捷鍵,或者沒發現瀏覽器隱藏的“編輯”選單,又或者沒用過右鍵選單,再或者不知道在觸控式螢幕上需要進行長按,後續的複製過程也很難簡單完成。

如果提供一個一鍵“複製到剪貼簿”按鈕,是不是就能幫到大家呢?這樣的話即使是熟練的鍵盤快手也會樂於使用吧。

剪貼簿的安全機制

幾年前,因為瀏覽器不具備直接訪問剪貼簿的能力,開發者只能藉助於Flash外掛來提供這一基本功能。

乍一看開放剪貼簿許可權似乎沒什麼危害,但試想如果瀏覽器能隨意檢視和操作剪貼簿內容的話,頁面指令碼(包括第三方指令碼)豈不是就能輕鬆偷窺其中的資訊然後將密碼,敏感資訊,甚至整個頁面傳送給遠端的伺服器了。

現在,我們已經可以整合基本的剪貼簿功能,但還是有一些限制:

  1. 大部分瀏覽器支援剪貼簿功能,Mac和iOS上的Safari除外。
  2. 不同瀏覽器的支援程度不盡相同,一些功能並不完整或存在缺陷。
  3. 使用者必須通過點選滑鼠或按鍵的方式來主動觸發,指令碼並不能隨時操縱剪貼簿。

document.execCommand() 方法

document.execCommand() 是需要呼叫的關鍵方法,它可以傳入的引數包括 ‘cut’, ‘copy’ 和 ‘paste’ 。這裡重點介紹最實用的 document.execCommand(‘copy’) 方法。

在呼叫之前,可以使用 document.queryCommandSupported(‘copy’); 或 document.queryCommandEnabled(‘copy’); 方法(這兩個方法功能相同)來檢測瀏覽器是否支援複製命令。需要注意的是,Chrome 雖然支援複製命令的,但在 Chorme 中這兩個方法都會返回 false 值。檢測 document.execCommand 方法是否存在也是一個判斷方法,但更好的做法是將 document.execCommand(‘copy’) 呼叫放在 try-catch 塊內。

接下來就得考慮使用者能複製什麼內容了,指令碼需要能夠選中文字,好在所有的瀏覽器都允許使用 select() 方法選擇文字輸入和文字區域的內容,並且在 Firefox 和 Chrome/Opera 瀏覽器中,還能使用 document.createRange 方法來從任何元素中選擇文字。

然而,IE/Edge 並不支援這一方法。

使用clipboard.js

如果你已經放棄打造一個高魯棒性的跨瀏覽器剪貼簿方案,那麼 clipboard.js 會是一個不錯的選擇。它提供了多種配置方法,例如通過新增 HTML5 資料屬性來指定觸發器和複製物件。

自己來實現

雖然 clipboard.js 只有 2kb,但我們只用20行程式碼就能實現,前提是你能接受以下條件:

  • 只有對應的表單區域能夠被複制
  • 在一些瀏覽器中無效(沒錯,就是Safari),但可以在選中文字後提示使用者使用快捷鍵 Ctrl/Cmd + C。

像 clipboard.js 一樣,我們會使用一個按鈕作為觸發器,新增資料屬性(data-copytarget)來指定拷貝內容的目標(#website):

下面的自執行函式會給所有帶有 data-copytarget 屬性的元素新增一個點選事件處理方法,去選中區域裡的文字並執行 document.execCommand(‘copy’) 。如果這一操作失敗了,文字將保持選中狀態同時彈出提示。

演示:

See the Pen JavaScript clipboard integration by SitePoint (@SitePoint) on CodePen.

演示因為附加了可選的樣式和動畫程式碼,所以程式碼數超過了了20行。

其他用途

你還可以設計出更棒的剪貼簿功能特性。例如,在 Trello.com 網站中,當你把滑鼠指標放在任何卡片上方時,使用快捷鍵 Ctrl/Cmd+C 就能將卡片的url複製到剪貼簿。實際上,程式建立了一個包含 URL 地址的隱藏表單然後進行了選中和複製。雖然我懷疑很少有使用者會知道這一功能,但這的確是實用又聰明的方法!

歡迎在評論區分享你的看法

相關文章