1. 程式人生 > 實用技巧 >前端操作剪下板不完全指北

前端操作剪下板不完全指北

由於瀏覽器隱私協議限制,以前瀏覽器是不允許直接訪問剪下板的,最近幾年,隨著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, '&lt;')
  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/png76+才行。返回值是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)

參考資料