2020年12月29日 星期二

Javascript 如何操作剪貼簿

參考自How do I copy to the clipboard in JavaScript?

Document.execCommand()

首先是歷史最悠久的

document.execCommand("cut");
document.execCommand("copy");
document.execCommand("paste");

這也是知名的 clipboard.js 用的方法。

缺點是,這方法已經過時,而且也不是所有的瀏覽器都支援(雖然大部分還是支援的)

clipboardData Object

第二種方法是使用 clipboardData 這個物件。

例如

var text = "扮一個漁翁,但想起我做父親的往迹,荊棘刺入了行路人的脛踝,或是我們執事的地方,她們又講你怎樣喜歡拿著一根短棍站在桌上摹仿音樂會的導師,身影似的不可解脫。"

window.clipboardData.setData("Text" , text)

這個方法會有安全性提示,如果允許,就會讓你複製這段字串。

缺點是,這方法是 IE only

Old Firefox Only

除了 IE only,也有 Firefox only 的方法

參閱MDN的«Using the clipboard»這篇文章,可以用下面這段 code 來複製文字到剪貼簿

var text = "扮一個漁翁,但想起我做父親的往迹,荊棘刺入了行路人的脛踝,或是我們執事的地方,她們又講你怎樣喜歡拿著一根短棍站在桌上摹仿音樂會的導師,身影似的不可解脫。"

gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
                                   .getService(Components.interfaces.nsIClipboardHelper);
gClipboardHelper.copyString(text);

但,雖然說是 Firefox only,實際上這方法我在 FF 24 是可以使用,但在最近這幾版,例如 84 版,的 Firefox 就不行

Async Clipboard API

第4種方法是使用 HTML 5 的Clipboard API

範例:

var text = "扮一個漁翁,但想起我做父親的往迹,荊棘刺入了行路人的脛踝,或是我們執事的地方,她們又講你怎樣喜歡拿著一根短棍站在桌上摹仿音樂會的導師,身影似的不可解脫。"

navigator.clipboard.writeText(text).then(function() {
	console.log("Copied Successfully")
})
.catch(function(err){
	console.error("Copied Failed", err)
})

由於 document.execCommand 的安全性問題,加上先前並沒有一個真正的剪貼簿 API 規範,所以才新增的。

這方法也不是沒有缺點,例如

  1. 只能用在 https 上
  2. 並非所有瀏覽器都完整支援,像是 Firefox 84 版,依舊不支援 navigator.clipboard.write() ,各 function 的支援程度可參考 MDN 文件
  3. 不能直接使用,必須在 Event 內執行。

關於上述第3點,舉例來說,直接執行以下 code ,會出現 Copied Fail. DOMException: Document is not focused.(Firefox 會是 Copied Fail. undefined)的錯誤訊息

var text = "扮一個漁翁,但想起我做父親的往迹,荊棘刺入了行路人的脛踝,或是我們執事的地方,她們又講你怎樣喜歡拿著一根短棍站在桌上摹仿音樂會的導師,身影似的不可解脫。"

navigator.clipboard.writeText(text).then(function() {
	console.log("Copied Successfully")
})
.catch(function(err){
	console.error("Copied Failed.", err)
})

要將這段 Code 放在某 Event 才可,例如


<button id="btn">Click Me</button>

<script>
document.getElementById("btn").addEventListener("click", function(){
	var text = "扮一個漁翁,但想起我做父親的往迹,荊棘刺入了行路人的脛踝,或是我們執事的地方,她們又講你怎樣喜歡拿著一根短棍站在桌上摹仿音樂會的導師,身影似的不可解脫。"

	navigator.clipboard.writeText(text).then(function() {
		console.log("Copied Successfully")
	})
	.catch(function(err){
		console.error("Copied Failed.", err)
	})
})
</script>

這樣點擊 button 後就會跳出 Copied Successfully 的 log 了。

但如果是用 dispatchEvent 來執行 Event,例如下面這樣,依舊會跳出錯誤訊息

document.getElementById("btn").dispatchEvent(new Event("click"))

Clipboard Event

Clipboard 除了上述的內容外,還有追加 cut / copy / post 三種 Clipboard Event。 詳見 W3C 的說明。 這三個 Event 可以更改剪貼簿的資料,但是必須要在使用者進行「剪下/複製/貼上」的動作時,才會執行。 想當然爾,和前面第幾種方法一樣,不能直接靠 javascript 執行。也因此缺乏主動性。

參考資料

  • Dean Taylor (2015-06-12). How do I copy to the clipboard in JavaScript? from https://stackoverflow.com/a/30810322

沒有留言:

張貼留言