使用系統提供的剪貼簿是一項基本的IT技能。作為一個開發者,相信你已經知道使用 Ctrl/Cmd+A, Ctrl/Cmd+C 以及 Ctrl/Cmd+V 組合鍵就能快捷地進行選中、複製、貼上。
但對於普通使用者來說就沒那麼容易了。即使使用者知道剪貼簿的存在,視力再好、反應再快的使用者也很難選中他們想要的文字。接下來,如果使用者沒有掌握快捷鍵,或者沒發現瀏覽器隱藏的“編輯”選單,又或者沒用過右鍵選單,再或者不知道在觸控式螢幕上需要進行長按,後續的複製過程也很難簡單完成。
如果提供一個一鍵“複製到剪貼簿”按鈕,是不是就能幫到大家呢?這樣的話即使是熟練的鍵盤快手也會樂於使用吧。
剪貼簿的安全機制
幾年前,因為瀏覽器不具備直接訪問剪貼簿的能力,開發者只能藉助於Flash外掛來提供這一基本功能。
乍一看開放剪貼簿許可權似乎沒什麼危害,但試想如果瀏覽器能隨意檢視和操作剪貼簿內容的話,頁面指令碼(包括第三方指令碼)豈不是就能輕鬆偷窺其中的資訊然後將密碼,敏感資訊,甚至整個頁面傳送給遠端的伺服器了。
現在,我們已經可以整合基本的剪貼簿功能,但還是有一些限制:
- 大部分瀏覽器支援剪貼簿功能,Mac和iOS上的Safari除外。
- 不同瀏覽器的支援程度不盡相同,一些功能並不完整或存在缺陷。
- 使用者必須通過點選滑鼠或按鍵的方式來主動觸發,指令碼並不能隨時操縱剪貼簿。
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 方法來從任何元素中選擇文字。
1 2 3 4 5 6 7 8 |
// select text in #myelement node // 選擇 #myelement 標籤中的文字 var myelement = document.getElementById('#myelement'), range = document.createRange(); range.selectNode(myelement); window.getSelection().addRange(range); |
然而,IE/Edge 並不支援這一方法。
使用clipboard.js
如果你已經放棄打造一個高魯棒性的跨瀏覽器剪貼簿方案,那麼 clipboard.js 會是一個不錯的選擇。它提供了多種配置方法,例如通過新增 HTML5 資料屬性來指定觸發器和複製物件。
1 2 |
<input id="copyme" value="text in this field will be copied" /> <button data-clipboard-target="#copyme">copy</button> |
自己來實現
雖然 clipboard.js 只有 2kb,但我們只用20行程式碼就能實現,前提是你能接受以下條件:
- 只有對應的表單區域能夠被複制
- 在一些瀏覽器中無效(沒錯,就是Safari),但可以在選中文字後提示使用者使用快捷鍵 Ctrl/Cmd + C。
像 clipboard.js 一樣,我們會使用一個按鈕作為觸發器,新增資料屬性(data-copytarget)來指定拷貝內容的目標(#website):
1 2 |
<input type="text" id="website" value="http://www.sitepoint.com/" /> <button data-copytarget="#website">copy</button> |
下面的自執行函式會給所有帶有 data-copytarget 屬性的元素新增一個點選事件處理方法,去選中區域裡的文字並執行 document.execCommand(‘copy’) 。如果這一操作失敗了,文字將保持選中狀態同時彈出提示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
(function() { 'use strict'; // click events // 新增點選事件 document.body.addEventListener('click', copy, true); // event handler // 新增時間處理方法 function copy(e) { // find target element // 搜尋目標元素 var t = e.target, c = t.dataset.copytarget, inp = (c ? document.querySelector(c) : null); // is element selectable? // 判斷元素是否能被選中 if (inp &amp;&amp; inp.select) { // select text // 選擇文字 inp.select(); try { // copy text // 複製文字 document.execCommand('copy'); inp.blur(); } catch (err) { alert('please press Ctrl/Cmd+C to copy'); } } } })(); |
演示:
See the Pen JavaScript clipboard integration by SitePoint (@SitePoint) on CodePen.
演示因為附加了可選的樣式和動畫程式碼,所以程式碼數超過了了20行。
其他用途
你還可以設計出更棒的剪貼簿功能特性。例如,在 Trello.com 網站中,當你把滑鼠指標放在任何卡片上方時,使用快捷鍵 Ctrl/Cmd+C 就能將卡片的url複製到剪貼簿。實際上,程式建立了一個包含 URL 地址的隱藏表單然後進行了選中和複製。雖然我懷疑很少有使用者會知道這一功能,但這的確是實用又聰明的方法!
歡迎在評論區分享你的看法