
現在有許多第三方外掛程式能夠實現copy 功能,但如果讓我們自己做,我們知道如何實現嗎?
這篇文章介紹三種實作方案。
使用Async Clipboard API
這種方式使用起來最簡單,但相容性不太好,而且要求比較多。

範例程式碼:
const promise = navigator.clipboard.writeText(newClipText);
需要注意,方法的回傳值是個Promise。並且使用此方法時,頁面必須處於focus 狀態,否則會報錯。
使用Document.execCommand
此方法雖然警告被廢棄,不再屬於web 標準,但歷史因素較多,相信瀏覽器還會支援很久。

<p id="content">123456</p> <button id="copyButton">複製</button>
複製DOM 元素的時候,需要額外使用到selection API 和Range API。
developer.mozilla.org/en-US/docs/…
developer.mozilla.org/en-US/docs/…
範例程式碼:
const copyButton = document.getElementById('copyButton');
const content = document.getElementById('content');
copyButton.addEventListener('click', function () {
const selection = window.getSelection();
const range = document.createRange();
// 設定選取內容range.selectNodeContents(content);
// 清空選取內容selection.removeAllRanges();
// 新增選取內容selection.addRange(range);
document.execCommand('copy');
}); selection 需要先清空再加入range。
這裡會有一個細節問題,點擊複製按鈕之後,被複製的內容處於選取狀態,有些突兀。
解決方式是複製完成之後呼叫selection.removeAllRanges()清空選取內容即可。
再考慮一種情況,使用者在複製之前就選取了頁面的部分內容。複製完成之後,除了清空選取的複製內容,還需要還原使用者在複製之前就選取的內容。
實作程式碼如下:
const copyButton = document.getElementById('copyButton');
const content = document.getElementById('content');
copyButton.addEventListener('click', function () {
const selection = window.getSelection();
const range = document.createRange();
// 快取使用者選取的內容const currentRange =
selection.rangeCount === 0 ? null : selection.getRangeAt(0);
// 設定文件片段range.selectNodeContents(content);
// 清空選取內容selection.removeAllRanges();
// 將文件片段設定為選取內容selection.addRange(range);
try {
// 複製到剪貼簿document.execCommand('copy');
} catch (err) {
// 提示複製失敗} finally {
selection.removeAllRanges();
if (currentRange) {
// 還原使用者選取內容selection.addRange(currentRange);
}
}
});先快取使用者選取的內容,複製完成之後,再還原。
使用input 元素物件的select方法即可選取內容,無需建立range 片段設定選取內容。
範例程式碼:
const copyButton = document.getElementById('copyButton');
const inputEl = document.getElementById('input');
copyButton.addEventListener('click', function () {
const selection = window.getSelection();
const currentRange =
selection.rangeCount === 0 ? null : selection.getRangeAt(0);
// 選取input 內容inputEl.select();
// 複製到剪貼簿try {
document.execCommand('copy');
} catch (err) {
// 提示複製失敗// 。 。 。
} finally {
selection.removeAllRanges();
if (currentRange) {
// 還原使用者選取內容selection.addRange(currentRange);
}
}
});點選複製按鈕,同樣不會移除先前選取的內容。
w3c.github.io/clipboard-a…
引用上面連結內的一段程式碼作為範例:
// Overwrite what is being copied to the clipboard.
document.addEventListener('copy', function (e) {
// e.clipboardData is initially empty, but we can set it to the
// data that we want copied onto the clipboard.
e.clipboardData.setData('text/plain', '西炒蛋');
// This is necessary to prevent the current document selection from
// being written to the clipboard.
e.preventDefault();
});在頁面複製任何內容,貼上輸出的內容都會是「西炒蛋」。