前言
在瀏覽器中,將資料複製到剪貼簿的方法有三種:
- Document.execCommand() 的
copy
指令 - Clipboard API
- ClipboardEvent 的
copy
、paste
事件
遠古時期還有使用 Flash 來操作剪貼簿,這裡就不討論了。
Document.execCommand()
Document.execCommand() 的 copy
指令能將選取到的內容複製到剪貼簿。
1. 複製操作
執行 document.execCommand('copy')
就可以將當前選取範圍複製到剪貼簿。
|
|
若要顯示當前選取內容值,可以使用 window.getSelection()
表示當前使用者選取的範圍或光標當前位置,回傳 Selection 物件,並使用 + ''
或 toString()
轉字串。
|
|
2. 複製輸入框內容
document.execCommand('copy')
的缺點就是只能複製選取的內容,如果我們要複製 <textarea>
或 <input type="text">
的內容值,可以使用 select()
選取內容值,再執行 document.execCommand('copy')
。
|
|
若 select()
在 iOS 無反應,使用 setSelectionRange
即可:
|
|
3. 複製指定元素文字
如果我們要複製某一個元素的文字內容,就需要建立選取範圍。
|
|
4. 複製任意內容
如果要將任意內容複製到剪貼簿,需要先建立 <textarea>
元素,並將指定內容設為 value
,再插入 DOM 樹中,呼叫 select()
與執行複製,最後刪除 <textarea>
元素。
|
|
優缺點
優點:
- 基本上支援所有主流瀏覽器。
Document API: execCommand: copy - Can I use
缺點:
- 只能複製選取中的內容,複製任意內容需要建立臨時的
<textarea>
可能導致畫面閃爍,而且還會取消使用者當前選取的內容。 - 同步操作,若複製大量資料,可能導致頁面卡頓。
Clipboard API
Clipboard API 是新一代的剪貼簿操作方法,被設計用來取代 document.execCommand()
,能直接訪問剪貼簿,為非同步操作,所有操作方法都會回傳 Promise 物件。
1. Clipboard 物件
navigator.clipboard
會回傳 Clipboard 物件,所有操作都是透過它進行。
|
|
若 navigator.clipboard
回傳 undefined
,表示當前瀏覽器不支援。
2. 安全和權限
直接訪問剪貼簿的操作其實並不安全,因此 Clipboard API 僅支持通過 HTTPS 提供的頁面(開發環境 localhost 例外),且必須使用者授權才能訪問。
若是在 <iframe>
中運行,父頁面必須授予 clipboard-read
(讀權限) 或 clipboard-write
(寫權限)。
|
|
另外,我們可以使用 Permissions API 的 Permissions.query()
查看是否有權訪問剪貼簿。
3. 操作方法
readText()
:讀取剪貼簿純文字內容。writeText()
:對剪貼簿寫入純文字內容。read()
:讀取剪貼簿複合內容。write()
:對剪貼簿寫入複合內容。
以上方法皆會回傳一個 Promise 物件,讀取方法有結果值可以接收,若使用者拒絕授權,會拋出 NotAllowedError。
|
|
也可以使用 async/await
語法:
|
|
優缺點
優點:
- 操作簡單,能直接訪問剪貼簿,不需要像
document.execCommand('copy')
需要有選取範圍才能使用。 - 非同步操作。
缺點:
- 需要使用者授權。
- 瀏覽器支援度不佳。
Clipboard API: readText- Can I use
Clipboard API: writeText- Can I use
Clipboard API: read- Can I use
Clipboard API: write- Can I use
ClipboardEvent
ClipboardEvent
介面描述了與修改剪貼簿相關的事件。當使用者執行剪貼簿相關的操作,我們可以透過監聽 cut
、copy
和 paste
,攔截事件以進行操作。
cut
、copy
和 paste
這些事件僅在當前頁面上操作時觸發。
這些事件的 event
物件中的 clipboardData
屬性 ,有三個方法可以使用:
clearData()
:清除剪貼簿資料,可指定資料類型,若不指定則清除全部。getData()
:取得剪貼簿資料,需要指定資料類型。setData()
:修改剪貼簿資料,需要指定資料類型。
1. 複製操作
當我們執行複製操作時,可以監聽 copy
事件,將指定內容放入剪貼簿。
|
|
我們有時候複製某些網站的內容時,會自動加上版權出處:
|
|
Clipboard.js
Clipboard.js 是一個將文字複製到剪貼簿的 JavaScript 函式庫,操作簡單、輕量、不依賴其他框架,依賴 Selection API 和 execCommand API 支持主流瀏覽器。
安裝:
# NPM 管理
npm install clipboard --save
# 引入 CDN
https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js
1. 基本用法
建立實體,傳入要綁定的元素:
|
|
可以是 DOM 選擇器 或 HTML 元素 或 HTML 元素陣列。
首先,若要複製當前的內容,可以使用 data-clipboard-text
設定內容值:
|
|
如果要從其他元素取值,可以透過 data-clipboard-target
指定目標元素:
|
|
目標為 <input>
或 <textarea>
可以複製內容值,若是 其他元素,例如 <div>
則複製元素中的文字。
預設操作為 copy
複製,使用 data-clipboard-action
可以設置 cut
剪下。
|
|
但只對 <input>
和 <textarea>
有作用。
2. 事件處理
如果想要在剪貼簿操作完成後執行其他操作,可以使用 success
或 error
自定義事件:
|
|
3. 進階用法
若不希望修改 HTML 程式碼(也就是使用 data-
),建立實體時,還可以傳入一個選項物件。
target
選項為一個函式,需要回傳一個 Node,作為目標元素:
|
|
text
選項為一個函式,需要回傳一個字串,作為複製內容:
|
|
container
選項能傳入獲得焦點的元素:
|
|
4. 清除
若使用 SPA 單頁應用程式,想更精確管理 DOM 生命週期,想清除事件、實體,可以使用 destroy()
。
|
|
參考文獻
- Async Clipboard API: Accessing the clipboard using JavaScript
- Cut, Copy and Paste in JavaScript with the Clipboard API
- A better way to copy text to Clipboard in JavaScript
- 關於 Clipboard API 主流瀏覽器支援程度分析
- Async Clipboard API:異步剪貼板 API
- 剪贴板操作 Clipboard API 教程
- 前端操作剪切板不完全指北
- 知乎上複製回答,剪貼板裡自動加上版權出處的技術js如何實現?
- clipboard.js 的源碼分析
- clipboard.js 核心代碼解析