摘要:在用戶執行粘貼操作的時候,能夠獲得剪切板的內容,本文討論一下這個問題。目前只有支持獲取剪切板中的圖片數據。這么多的判斷條件,基本可以確定通過剪切板過來的是粘貼的文件。
在用戶執行粘貼操作的時候,js能夠獲得剪切板的內容,本文討論一下這個問題。
目前只有Chrome支持獲取剪切板中的圖片數據。還好需要這個功能的產品目前只支持Chrome和Safari,一些Chrome的新特性是可以盡情使用了,還是能夠覆蓋到大部分用戶的。所以本文只討論Chrome如何使用和如何阻止Safari,原理大概了解了,再研究其他瀏覽器相關的問題就容易多了。
paste事件可以用js給頁面中的元素綁定paste事件的方法,當用戶鼠標在該元素上或者該元素處于focus狀態,綁定到paste事件的方法就運行了。
綁定的元素不一定是input,普通的div也是可以綁定的,如果是給document綁定了,就相當于全局了,任何時候的粘貼操作都會觸發。
事件對象 獲取事件對象先寫一下事件綁定的代碼
pasteEle.addEventListener("paste", function (e){ if ( !(e.clipboardData && e.clipboardData.items) ) { return; } });
粘貼事件提供了一個clipboardData的屬性,如果該屬性有items屬性,那么就可以查看items中是否有圖片類型的數據了。Chrome有該屬性,Safari沒有。
clipboardData介紹介紹一下clipboardData對象,它實際上是一個DataTransfer類型的對象,DataTransfer 是拖動產生的一個對象,但實際上粘貼事件也是它。
clipboardData的屬性介紹
屬性 | 類型 | 說明 |
---|---|---|
dropEffect | String | 默認是 none |
effectAllowed | String | 默認是 uninitialized |
files | FileList | 粘貼操作為空List |
items | DataTransferItemList | 剪切板中的各項數據 |
types | Array | 剪切板中的數據類型 該屬性在Safari下比較混亂 |
items是一個DataTransferItemList對象,自然里面都是DataTransferItem類型的數據了。
屬性items的DataTransferItem有兩個屬性kind和type
屬性 | 說明 |
---|---|
kind | 一般為string或者file |
type | 具體的數據類型,例如具體是哪種類型字符串或者哪種類型的文件,即MIME-Type |
方法 | 參數 | 說明 |
---|---|---|
getAsFile | 空 | 如果kind是file,可以用該方法獲取到文件 |
getAsString | 回調函數 | 如果kind是string,可以用該方法獲取到字符串,字符串需要用回調函數得到,回調函數的第一個參數就是剪切板中的字符串 |
在原型上還有一些其他方法,不過在處理剪切板操作的時候一般用不到了。
types介紹一般types中常見的值有text/plain、text/html、Files。
值 | 說明 |
---|---|
text/plain | 普通字符串 |
text/html | 帶有樣式的html |
Files | 文件(例如剪切板中的數據) |
pasteEle.addEventListener("paste", function (e){ if ( !(e.clipboardData && e.clipboardData.items) ) { return ; } for (var i = 0, len = e.clipboardData.items.length; i < len; i++) { var item = e.clipboardData.items[i]; if (item.kind === "string") { item.getAsString(function (str) { // str 是獲取到的字符串 }) } else if (item.kind === "file") { var pasteFile = item.getAsFile(); // pasteFile就是獲取到的文件 } } });
注意如果是string類型的數據,可能針對具體是text/plain、text/html進行分別的處理。
問題來了一切看似都很順利,如果用戶粘貼了圖片,通過上面的方法我們是可以獲取到,可以對圖片進行上傳等操作了。
首先要說一下js通過剪切板能獲取到的圖片是怎么來的,它必須是用QQ截圖或者系統截圖功能截下來的圖片,或者是網頁上某個圖片單擊右鍵復制圖片等。
但是如果用戶復制Mac的Finder中的一個圖片文件,實際上js是沒有辦法獲取到這個圖片的。但是js確實會獲得一個圖片類型的文件,這個圖片實際上圖片在電腦中的圖標標識,說的比較抽象,直接上圖。
如果復制的是JPEG圖片,粘貼過來的卻是Mac上的文件縮略圖,后面依次是PNG、GIF、ZIP、DMG、Mac目錄的文件縮略圖。
很明顯,這不是我們期待得到的粘貼的結果,我們期待得到文件,但實際上卻得到該文件在操作系統上的縮略圖。
不過粘貼事件帶來的數據還有一個字符串,就是該文件的名字,所以可以用下面的方法Hack掉。
var cbd = e.clipboardData; if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" && cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files"){ return; }
這么多的判斷條件,基本可以確定通過剪切板過來的是粘貼的文件。我剛才測試了Windows的Chrome,不會有這個問題,當然也不能通過復制文件的方法得到任何文件。
問題又來了當我打算寫這篇博客的時候,Chrome開發版已經升級到了49,上面的Bug突然消失了,囧。
所以上面的Hack應該加上版本限制了。
var ua = window.navigator.userAgent; ua.match(/Macintosh/i) && Number(ua.match(/Chrome/(d{2})/i)[1]) < 49
應該在上面的Hack再加上這兩個判斷,即是Mac下的Chrome49版本以下就要return。
探究過程走的一點彎路由于公司IM系統正在遷移到V2消息系統,而且現有的文件類庫沒有辦法滿足業務需求,要自己封裝一個文件上傳庫。
然后副總找到產品經理,說新版怎么不支持Excel的粘貼,臨時排期一天修復這個問題,當時是這樣解決的,如果items長度是1并且是文件類型(單純粘貼一個文件),則上傳,如果items長度是4且第4個是文件類型(經過測試是Excel的粘貼結果),則上傳。
當時擔心由于用戶各種誤操作,粘貼了不該粘貼的東西,文件上傳錯誤,用了這種白名單機制去過濾,但是萬一以后有比Excel粘貼得到的數據更其他的類型,就需要多帶帶寫代碼兼容,所以,現在改成了如果判斷是有Bug的情況,直接return,屬于黑名單機制,這樣以后再發現黑名單的情況,再添加。
可以拿來就用的代碼// demo 程序將粘貼事件綁定到 document 上 document.addEventListener("paste", function (e) { var cbd = e.clipboardData; var ua = window.navigator.userAgent; // 如果是 Safari 直接 return if ( !(e.clipboardData && e.clipboardData.items) ) { return; } // Mac平臺下Chrome49版本以下 復制Finder中的文件的Bug Hack掉 if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" && cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" && ua.match(/Macintosh/i) && Number(ua.match(/Chrome/(d{2})/i)[1]) < 49){ return; } for(var i = 0; i < cbd.items.length; i++) { var item = cbd.items[i]; if(item.kind == "file"){ var blob = item.getAsFile(); if (blob.size === 0) { return; } // blob 就是從剪切板獲得的文件 可以進行上傳或其他操作 } } }, false);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78477.html
摘要:屬性介紹默認是默認是在粘貼操作時為空剪切板中的各項數據剪切板中的數據類型。避免重復創建上傳中文件成功失敗處理已上傳上傳出錯添加文件到隊列并上傳開始上傳其他參考獲取剪切板內容,控制圖片粘貼在線代碼編輯器事件說明 Markdown編輯器選用https://simplemde.com它是一款純js實現的markdown編輯器。缺點不支持圖片上傳。那我們就得改造它。simplemde是基于co...
摘要:取消默認的復制事件被復制的文字等下插入防知乎掘金復制一兩個字則不添加版權信息超過一定長度的文字就添加版權信息作者鏈接來源掘金著作權歸作者所有。以上參考資料高程操作剪貼板網頁上如何實現禁止復制粘貼以及如何破解原生實現點擊按鈕復制文本 showImg(https://segmentfault.com/img/remote/1460000015942602?w=1280&h=720); 前言...
摘要:取消默認的復制事件被復制的文字等下插入防知乎掘金復制一兩個字則不添加版權信息超過一定長度的文字就添加版權信息作者鏈接來源掘金著作權歸作者所有。以上參考資料高程操作剪貼板網頁上如何實現禁止復制粘貼以及如何破解原生實現點擊按鈕復制文本 showImg(https://segmentfault.com/img/remote/1460000015942602?w=1280&h=720); 前言...
摘要:取消默認的復制事件被復制的文字等下插入防知乎掘金復制一兩個字則不添加版權信息超過一定長度的文字就添加版權信息作者鏈接來源掘金著作權歸作者所有。以上參考資料高程操作剪貼板網頁上如何實現禁止復制粘貼以及如何破解原生實現點擊按鈕復制文本 showImg(https://segmentfault.com/img/remote/1460000015942602?w=1280&h=720); 前言...
閱讀 3593·2021-11-23 09:51
閱讀 2795·2021-11-23 09:51
閱讀 676·2021-10-11 10:59
閱讀 1672·2021-09-08 10:43
閱讀 3223·2021-09-08 09:36
閱讀 3288·2021-09-03 10:30
閱讀 3293·2021-08-21 14:08
閱讀 2195·2021-08-05 09:59