新聞中心
這篇文章主要講解了“怎么實現(xiàn)復(fù)制圖像”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么實現(xiàn)復(fù)制圖像”吧!
創(chuàng)新互聯(lián)建站10多年成都企業(yè)網(wǎng)站建設(shè)服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及高端網(wǎng)站定制服務(wù),成都企業(yè)網(wǎng)站建設(shè)及推廣,對柔性防護網(wǎng)等多個方面擁有多年的網(wǎng)站設(shè)計經(jīng)驗的網(wǎng)站建設(shè)公司。
在寫了 這個 29.7 K 的剪貼板 JS 庫有點東西! 這篇文章之后,收到了小伙伴提的兩個問題:
1.clipboard.js 這個庫除了復(fù)制文字之外,能復(fù)制圖像么?
2.clipboard.js 這個庫依賴的 document.execCommand API 已被廢棄了,以后應(yīng)該怎么辦?

接下來,本文將圍繞上述兩個問題展開,不過在看第一個問題之前,我們先來簡單介紹一下 剪貼板 ?。
剪貼板(英語:clipboard),有時也稱剪切板、剪貼簿、剪貼本。它是一種軟件功能,通常由操作系統(tǒng)提供,作用是使用復(fù)制和粘貼操作短期存儲數(shù)據(jù)和在文檔或應(yīng)用程序間轉(zhuǎn)移數(shù)據(jù)。它是圖形用戶界面(GUI)環(huán)境中最常用的功能之一,通常實現(xiàn)為匿名、臨時的數(shù)據(jù)緩沖區(qū),可以被環(huán)境內(nèi)的大部分或所有程序使用編程接口訪問。—— 維基百科
通過以上的描述我們可以知道,剪貼板架起了一座橋梁,使得在各種應(yīng)用程序之間,傳遞和共享信息成為可能。然而美中不足的是,剪貼板只能保留一份數(shù)據(jù),每當(dāng)新的數(shù)據(jù)傳入,舊的便會被覆蓋。
了解完 剪貼板 ? 的概念和作用之后,我們馬上來看一下第一個問題:clipboard.js 這個庫除了復(fù)制文字之外,能復(fù)制圖像么?
一、clipboard.js 能否復(fù)制圖像?
clipboard.js 是一個用于將 文本 復(fù)制到剪貼板的 JS 庫。沒有使用 Flash,沒有使用任何框架,開啟 gzipped 壓縮后僅僅只有 3kb。

(圖片來源:https://clipboardjs.com/#example-text)
當(dāng)你看到 “A modern approach to copy text to clipboard” 這個描述,你是不是已經(jīng)知道答案了。那么實際的情況是怎樣呢?下面我們來動手驗證一下。在 這個 29.7 K 的剪貼板 JS 庫有點東西! 這篇文章中,阿寶哥介紹了在實例化 ClipboardJS 對象時,可以通過 options 對象的 target 屬性來設(shè)置復(fù)制的目標:
// https://github.com/zenorocha/clipboard.js/blob/master/demo/function-target.html let clipboard = new ClipboardJS('.btn', { target: function() { return document.querySelector('div'); } });
利用 clipboard.js 的這個特性,我們可以定義以下 HTML 結(jié)構(gòu):
![]()
大家好,我是阿寶哥
上面的頁面結(jié)構(gòu)很簡單,下一步我們來逐步分析一下以上功能的實現(xiàn)過程。
5.1 請求剪貼板寫權(quán)限
默認情況下,會為當(dāng)前的激活的頁面自動授予剪貼板的寫入權(quán)限。出于安全方面考慮,這里我們還是主動向用戶請求剪貼板的寫入權(quán)限:
async function askWritePermission() { try { const { state } = await navigator.permissions.query({ name: "clipboard-write", }); return state === "granted"; } catch (error) { return false; } }
5.2 往剪貼板寫入圖像和普通文本數(shù)據(jù)
要往剪貼板寫入圖像數(shù)據(jù),我們就需要使用 navigator.clipboard 對象提供的 write 方法。如果要寫入圖像數(shù)據(jù),我們就需要獲取該圖像對應(yīng)的 Blob 對象,這里我們可以通過 fetch API 從網(wǎng)絡(luò)上獲取圖像對應(yīng)的響應(yīng)對象并把它轉(zhuǎn)化成 Blob 對象,具體實現(xiàn)方式如下:
async function createImageBlob(url) { const response = await fetch(url); return await response.blob(); }
而對于普通文本來說,只需要使用前面介紹的 Blob API 就可以把普通文本轉(zhuǎn)換為 Blob 對象:
function createTextBlob(text) { return new Blob([text], { type: "text/plain" }); }
在創(chuàng)建完圖像和普通文本對應(yīng)的 Blob 對象之后,我們就可以利用它們來創(chuàng)建 ClipboardItem 對象,然后再調(diào)用 write 方法把這些數(shù)據(jù)寫入到剪貼板中,對應(yīng)的代碼如下所示:
async function writeDataToClipboard() { if (askWritePermission()) { if (navigator.clipboard && navigator.clipboard.write) { const textBlob = createTextBlob("大家好,我是阿寶哥"); const imageBlob = await createImageBlob( "http://cdn.semlinker.com/abao.png" ); try { const item = new ClipboardItem({ [textBlob.type]: textBlob, [imageBlob.type]: imageBlob, }); select(document.querySelector("#container")); await navigator.clipboard.write([item]); console.log("文本和圖像復(fù)制成功"); } catch (error) { console.error("文本和圖像復(fù)制失敗", error); } } } }
在以上代碼中,使用了一個 select 方法,該方法用于實現(xiàn)選擇的效果,對應(yīng)的代碼如下所示:
function select(element) { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); }
通過 writeDataToClipboard 方法,我們已經(jīng)把圖像和普通文本數(shù)據(jù)寫入剪貼板了。下面我們來使用 navigator.clipboard 對象提供的 read 方法,來讀取已寫入的數(shù)據(jù)。如果你需要讀取剪貼板的數(shù)據(jù),則需要向用戶請求 clipboard-read 權(quán)限。
5.3 請求剪貼板讀取權(quán)限
這里我們定義了一個 askReadPermission 函數(shù)來向用戶請求剪貼板讀取權(quán)限:
async function askReadPermission() { try { const { state } = await navigator.permissions.query({ name: "clipboard-read", }); return state === "granted"; } catch (error) { return false; } }
當(dāng)調(diào)用 askReadPermission 方法后,將會向當(dāng)前用戶請求剪貼板讀取權(quán)限,對應(yīng)的效果如下圖所示:

5.4 讀取剪貼板中已寫入的數(shù)據(jù)
創(chuàng)建好 askReadPermission 函數(shù),我們就可以利用之前介紹的 navigator.clipboard.read 方法來讀取剪貼板的數(shù)據(jù)了:
async function readDataFromClipboard() { if (askReadPermission()) { if (navigator.clipboard && navigator.clipboard.read) { try { const clipboardItems = await navigator.clipboard.read(); for (const clipboardItem of clipboardItems) { console.dir(clipboardItem); for (const type of clipboardItem.types) { const blob = await clipboardItem.getType(type); console.log("已讀取剪貼板中的內(nèi)容:", await blob.text()); } } } catch (err) { console.error("讀取剪貼板內(nèi)容失敗: ", err); } } } }
其實,除了點擊 粘貼 按鈕之外,我們還可以通過監(jiān)聽 paste 事件來讀取剪貼板中的數(shù)據(jù)。需要注意的是,如果當(dāng)前的瀏覽器不支持異步 Clipboard API,我們可以通過 clipboardData.getData 方法來讀取剪貼板中的文本數(shù)據(jù):
document.addEventListener('paste', async (e) => { e.preventDefault(); let text; if (navigator.clipboard) { text = await navigator.clipboard.readText(); } else { text = e.clipboardData.getData('text/plain'); } console.log('已獲取的文本數(shù)據(jù): ', text); });
而對于圖像數(shù)據(jù),則可以通過以下方式進行讀?。?/p>
const IMAGE_MIME_REGEX = /^image\/(p?jpeg|gif|png)$/i; document.addEventListener("paste", async (e) => { e.preventDefault(); if (navigator.clipboard) { let clipboardItems = await navigator.clipboard.read(); for (const clipboardItem of clipboardItems) { for (const type of clipboardItem.types) { if (IMAGE_MIME_REGEX.test(type)) { const blob = await clipboardItem.getType(type); loadImage(blob); return; } } } } else { const items = e.clipboardData.items; for (let i = 0; i < items.length; i++) { if (IMAGE_MIME_REGEX.test(items[i].type)) { loadImage(items[i].getAsFile()); return; } } } });
以上代碼中的 loadImage 方法用于實現(xiàn)把復(fù)制的圖片插入到當(dāng)前選區(qū)已選擇的區(qū)域中,對應(yīng)的代碼如下:
function loadImage(file) { const reader = new FileReader(); reader.onload = function (e) { let img = document.createElement("img"); img.src = e.target.result; let range = window.getSelection().getRangeAt(0); range.deleteContents(); range.insertNode(img); }; reader.readAsDataURL(file); }
感謝各位的閱讀,以上就是“怎么實現(xiàn)復(fù)制圖像”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么實現(xiàn)復(fù)制圖像這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
本文題目:怎么實現(xiàn)復(fù)制圖像
標題網(wǎng)址:http://fisionsoft.com.cn/article/jjpspi.html