在網頁中貼上截圖那些事兒

發表於2016-12-18

做這個嘗試,只為了解決一個問題:如何在網頁中讀取剪貼簿中的圖片資料,並在頁面中展示或儲存到圖片伺服器。場景可以簡單描述為,通過任意螢幕截圖工具(QQ、旺旺,PrintScreen鍵等),截圖之後網頁中的文字框內貼上(Ctrl+V、右鍵等),並在頁面中使用圖片資料。文字描述比較抽象,我們用一個gif圖片來形象的展示一下效果:

在網頁中貼上截圖那些事兒

ClipboardEvent(剪貼簿事件)

ClipboardEvent 介面描述了與修改剪下板相關的事件,這些事件包括 cut 、copy 和 paste 事件。

先解決一個問題:為什麼要說ClipboardEvent?

首先,無論是截圖還是在網頁中“複製圖片”,最終都是將圖片資料儲存到了系統剪貼簿中。其次,當執行“貼上”操作的時候是將剪貼簿中的資料讀出來使用,而讀取剪貼簿中的圖片(檔案)資料,更需要直接使用paste事件完成。

第二個問題:為什麼要在文字框中“貼上”,是必須的嗎?

先從paste事件來說,經測試paste事件可以繫結到任意HTML元素上的,並非必須使用文字框。再來猜測下使用場景,貼上操作涉及到資料寫入問題,內容不可能寫入到頁面中的只讀區域,所以按常理來說,只可能是貼上到頁面中的可寫區域。再者,最容易讓人想到的場景便是一個聊天會話,因此首先想到的便是文字框控制元件。

功能實現

功能邏輯比較簡單,截圖完成或在網頁中複製圖片後,圖片資料就儲存到系統剪貼簿上了。我們程式碼中需要實現的就是在paste事件中實現剪貼簿中的影象資料讀取和處理邏輯。拿到影象資料後,就可以根據自己的業務邏輯進行下一步操作了。程式碼如下:

程式碼很簡單,但有些細節需要注意。在MDN的paste事件說明文件中有說明,資料是存放在事件物件的clipboardData屬性中的。而在對clipboardData(DataTransfer型別)的說明中,檔案型別的資料應該是被存放在files屬性中。這一點在使用拖拽上傳等情況時確實是這樣的,但是在對截圖和複製的網頁圖片的處理上,各瀏覽器的實現似乎出現了差異。

在Chrome瀏覽器中,從剪貼簿讀取檔案時,files屬性中並沒有內容,而在items屬性中卻可以找到。而在Firefox中,files屬性中存在圖片資料,而在items中卻找不到檔案型別的資料。因此,我不得不在上示程式碼中做了存在性判斷,增加了額外的邏輯。

此外,IE瀏覽器對剪貼簿的處理比較特殊,它將剪貼簿資料放在了window作用域下,通過window.clipboardData對剪貼簿資料進行操作。但在IE Edge中測試,並未對截圖資料進行成功讀取,暫不做描述。

其他

如上程式碼所示,當clipboardData物件中的files屬性中沒有資料時,我們可以通過遍歷items中的元素,並通過元素的kindtype屬性判斷元素型別,最後通過getAsFile方法將元素轉換為檔案型別。

其實除了getAsFile方法,還有一個類似的方法,可以將元素轉換成字串,用法示例如下:

該方法可以根據複製源的不同,轉換出包含文字格式(比如:字型、字號等)的字串,如圖:

getasstring

對於文字型別的處理,相信是非常有用的一個方法。

結束語

目前,剪貼簿事件還是試驗中的功能,在後續的標準文件中可能被修改。我們在實際使用中應該做好相容處理,附相容性參考線上演示

相關文章