我從Typoro中學到的Clipboard妙用(二).md

一顆小行星發表於2021-11-25

上篇介紹了一下我從Typora中學到的Clipboard妙用:我們從網頁複製文字時,剪下板中會塞入兩種格式的資料:純文字和富文字。當我們貼上到其他編輯器時,文字編輯器會使用純文字資料,富文字編輯器會使用富文字資料(Typora中會把對應的文字提取成MarkDown格式)。

具體內容和簡單的程式碼實現可以檢視:我從Typora中學到的Clipboard妙用.md

Typora中圖片處理方式

經常使用Typora的人應該都知道Typora對於處理圖片也有著優秀的使用體驗,當插入圖片時,你可以指定圖片儲存方式:

Typora中處理圖片上傳方式

當我們插入圖片時,上傳服務會把剪下板中的圖片或拖拽的圖片自動上傳,替換成網路地址。這樣當你傳送文件給別人時或者釋出文件到部落格時,不會因為文件在本地而無法檢視。

本地檔案自動上傳並替換為線上地址

我自己也寫了一個小工具:file-uploader-cli ,可以處理檔案上傳到對應的儲存服務,比如githubftp、物件儲存等,可以訪問github地址檢視具體的配置方法(uPic和Picgo也支援Typora)。

對於自定義上傳服務,當有圖片插入時,Typora會呼叫上傳服務並傳入檔案路徑,上傳服務在控制檯列印上傳結果即可。

讀取剪下板中圖片資料

我們還是在控制檯中進行快速測試,開啟任意網頁,在element皮膚中找到任意標籤新增contenteditable屬性,當前標籤就變成可編輯元素了。

<p contenteditable>
  xxxx
</p>

控制檯中執行程式碼:

document.addEventListener('paste', function(e){
    console.log(e)
    const items = e.clipboardData.items;
    console.log(items)
    const fileList = e.clipboardData.files
    console.log(fileList)
    for(let i=0;i< items.length;i++){
        console.log(items[i])
        let f = items[i].getAsFile()
        console.log(f)
    }
    e.preventDefault();
})
本地檔案

複製本地檔案(可以是圖片或者其他格式檔案),並在標籤中執行貼上操作:

複製本地檔案

從上圖可以看出,從clipboardData中取出圖片資料有兩種方式:

  • e.clipboardData.items,是一個DataTransferItemList型別資料,每個元素是一個DataTransferItem型別,可以通過DataTransferItem.getAsFile()獲取到File物件
  • e.clipboardData.files 是一個FileList, 每個元素是一個File
只有當貼上的是本地檔案時,DataTransferItem.getAsFile才可以獲取到資料,否則為null。
網路圖片

當複製的資料是網路圖片時,分為兩種情況:

  • 只包含網路圖片
  • 包含網路圖片和文字

當複製的是網路圖片(從網頁直接右鍵複製圖片)時,clipboard會得到兩種資料:text/htmlimage/png。具體可以參考:我從Typora中學到的Clipboard妙用.md

只複製網路圖片

包含網路圖片和文字時,clipboard會得到:text/plaintext/html
包含網路圖片和文字

所以對於包含網路圖片的兩種方式,在paste事件中獲取到的資料也是不同的:

只包含圖片

包含圖片和文字

獲取圖片檔案

從上面的資訊我們可以瞭解到:只有當貼上的為本地影像和網路圖片時,我們可以通過DataTransferItem.getAsFile獲取到圖片物件;當包含文字時可以通過DataTransferItem.getAsString獲取到純文字和富文字資料。

Typora是如何處理圖片資料的
貼上圖片到Typora

如果是本地檔案,Typora會根據偏好設定中的圖片設定進行儲存:

  • 當選擇“上傳服務”時,會將本地圖片地址傳給自定義的圖片上傳服務,如果上傳成功則替換成網路地址;如果上傳失敗則保持本地圖片的引用。
  • 如果選擇了其他配置,則會複製圖片到對應配置的資料夾下。

如果是剪下板中的非本地圖片(比如截圖複製),會先儲存成本地檔案,再進行上傳或複製。

如果是富文字資料,會直接進行渲染(未勾選對網路位置的圖片應用上述規則)。

拖拽圖片到Typora

Typora支援paste圖片自動上傳,也支援拖拽圖片上傳,我們可以通過Drop Event獲取到File物件

document.addEventListener('drop', function(e){
    console.log(e)
    const items = e.dataTransfer.items;
    console.log(items)
    const fileList = e.dataTransfer.files
    console.log(fileList)
    e.preventDefault();
})

拖拽資料儲存在DragEvent.dataTransfer中:

拖拽插入圖片

chaos-fe

相關文章