前端操作剪下板不完全指北
由於瀏覽器隱私協議限制,以前瀏覽器是不允許直接訪問剪下板的,最近幾年,隨著web
應用興起,W3C
也在逐漸拓寬JavaScript
應用範圍,現在前端也能直接操作剪下板。文中按照訪問方式,分為間接訪問和直接訪問。
間接訪問
互動事件
使用者互動事件,如paste
(複製)、cut
(剪下)、dragstart
(拖拽)等,能夠通過事件物件Event
,訪問到剪下板。可以通過這部分操作,我們可以格式化、自定義剪下板中內容。在contenteditable
(可編輯)元素中,為了統一貼上文字樣式,我們可以在元素的複製事件中,對文字格式進行過濾。
let editor = document.getElementById('editor) editor.addEventListener('paste', e => { e.preventDefault() let data = e.clipboardData.getData('text/plain') // 格式化貼上xml標籤 data = data.replace(/>/g, '>') .replace(/</g, '<') let result = data.split('/n').join('<br />') document.execCommand('insertHTML', null, result) })
除了文字,我們還能獲取其他內容嗎?比如影象?答案是一半一半。為什麼說一半一半?
正常情況下,我們用截圖軟體截圖,這部分是能在e.dataTransfer.files
中獲取到的,截圖軟體實際上是將base64
檔案放到了剪下板中。但是,假如我們在作業系統中複製一張圖片,在dataTransfer
物件中,是獲取不到的,這是瀏覽器隱私協議限制,正如web
頁面不能直接作業系統檔案(雖然部分瀏覽器已經支援File API
)一樣,遇到這種需求,需要先放一放。
在業務開發中,測試童鞋們,總是能給人一些驚喜,誰說只能貼上,我還可以拖拽,拖拽一些奇奇怪怪的內容進去,看,又發現一個Bug
。可編輯元素預設是允許拖拽的,為避免這種方式,給我們的選擇只有兩個,第一,禁止拖拽,可以,但是比較暴力,第二就是改寫拖拽內容,監聽dragstart
let editor = document.getElementById('editor)
editor.addEventListener('dragstart', e => {
e.preventDefault()
// 獲取頁面選中文字
let selection = window.getSelection()
let data = selection.toString()
e.dataTransfer.setData('text/plain', data)
})
直接訪問
clipboard API
最近navigator
新增了Clipboard API
,不僅能夠對剪下板文字、檔案讀取,還提供了寫的操作,但是相容性較差。文字讀寫Chrome 66
image/png
得76+
才行。返回值是Promise
,用起來比較方便,但是對於剪下板的訪問,首先需要執行在https
服務頁面中,其次需要請求使用者授權,授權通過後,才能訪問。基本使用示例如下:
// 讀取文字
navigator.clipboard.readText().then(
clipText => document.getElementById("editor").innerText = clipText
);
// 讀取剪下板中圖片
navigator.permissions.query({name: "clipboard-read"}).then(result => {
if (result.state == "granted" || result.state == "prompt") {
navigator.clipboard.read().then(data => {
for (let i=0; i<data.items.length; i++) {
if (data.items[i].type != "image/png") {
alert("Clipboard contains non-image data. Unable to access it.");
} else {
const blob = data.items[i].getType("image/png");
imgElem.src = URL.createObjectURL(blob);
}
}
});
}
});
electron clipboard
electron
現在被越來越多的公司納入到桌面應用開發中。由於剪下板操作一直是web
應用開發的一個痛點,在electron
中,不管主程序還是渲染程序,都能使用剪下板API
,操作也豐富許多,不僅能夠操作文字、檔案,還能操作Buffer
,使得很多操作都成為可能。
const { clipboard } = require('electron')
clipboard.writeText('hello i am a bit of text!')
const text = clipboard.readText()
console.log(text)