中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現復制圖像

發布時間:2021-10-21 13:51:12 來源:億速云 閱讀:161 作者:iii 欄目:web開發

這篇文章主要講解了“怎么實現復制圖像”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么實現復制圖像”吧!

在寫了 這個 29.7 K 的剪貼板 JS 庫有點東西! 這篇文章之后,收到了小伙伴提的兩個問題:

1.clipboard.js 這個庫除了復制文字之外,能復制圖像么?

2.clipboard.js 這個庫依賴的 document.execCommand API 已被廢棄了,以后應該怎么辦?

怎么實現復制圖像

接下來,本文將圍繞上述兩個問題展開,不過在看第一個問題之前,我們先來簡單介紹一下 剪貼板 ?。

  • 剪貼板(英語:clipboard),有時也稱剪切板、剪貼簿、剪貼本。它是一種軟件功能,通常由操作系統提供,作用是使用復制和粘貼操作短期存儲數據和在文檔或應用程序間轉移數據。它是圖形用戶界面(GUI)環境中最常用的功能之一,通常實現為匿名、臨時的數據緩沖區,可以被環境內的大部分或所有程序使用編程接口訪問。——  維基百科

通過以上的描述我們可以知道,剪貼板架起了一座橋梁,使得在各種應用程序之間,傳遞和共享信息成為可能。然而美中不足的是,剪貼板只能保留一份數據,每當新的數據傳入,舊的便會被覆蓋。

了解完 剪貼板 ? 的概念和作用之后,我們馬上來看一下第一個問題:clipboard.js 這個庫除了復制文字之外,能復制圖像么?

一、clipboard.js 能否復制圖像?

clipboard.js 是一個用于將 文本 復制到剪貼板的 JS 庫。沒有使用  Flash,沒有使用任何框架,開啟 gzipped 壓縮后僅僅只有 3kb。

怎么實現復制圖像

(圖片來源:https://clipboardjs.com/#example-text)

當你看到 “A modern approach to copy text to clipboard”  這個描述,你是不是已經知道答案了。那么實際的情況是怎樣呢?下面我們來動手驗證一下。在 這個 29.7 K 的剪貼板 JS 庫有點東西!  這篇文章中,阿寶哥介紹了在實例化 ClipboardJS 對象時,可以通過 options 對象的 target 屬性來設置復制的目標:

// 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 結構:

<div id="container">    <img src="http://cdn.semlinker.com/abao.png" width="80" height="80"/>    <p>大家好,我是阿寶哥</p> </div> <button class="btn">復制</button>

然后在實例化 ClipboardJS 對象時設置復制的目標是 #container 元素:

const clipboard = new ClipboardJS(".btn", {   target: function () {     return document.querySelector("#container");   } });

之后,我們點擊頁面中的 復制 按鈕,對應的效果如下圖所示:

 怎么實現復制圖像

觀察上圖可知,頁面中的圖像和文本都已經被復制了。對于文本來說,大家應該都很清楚。而對于圖像來說,到底復制了什么?我們又該如何獲取已復制的內容呢?針對這個問題,我們可以利用  HTMLElement 對象上的 onpaste 屬性或者監聽元素上的 paste 事件。

這里我們通過設置 document 對象的 onpaste 屬性,來打印一下粘貼事件對應的事件對象:

document.onpaste = function (e) {   console.dir(e); }

當我們點擊 復制 按鈕,然后在頁面執行 粘貼 操作后,控制臺會打印出以下內容:

怎么實現復制圖像

通過上圖可知,在 ClipboardEvent 對象中含有一個 clipboardData 屬性,該屬性包含了與剪貼板相關聯的數據。詳細分析了  clipboardData 屬性之后,我們發現已復制的圖像和普通文本被封裝為 DataTransferItem 對象。

為了更方便地分析 DataTransferItem 對象,阿寶哥重新更新了 document 對象的 onpaste屬性:

怎么實現復制圖像

在上圖中,我們可以清楚的看到 DataTransferItem 對象上含有 kind 和 type 屬性分別用于表示數據項的類型(string 或  file)及數據對應的 MIME 類型。利用 DataTransferItem 對象提供的 getAsString  方法,我們可以獲取該對象中保存的數據:

怎么實現復制圖像

相信看完以上的輸出結果,小伙伴們就很清楚第一個問題的答案了。那么如果想要復制圖像的話,應該如何實現呢?其實這個問題的答案與小伙伴提的第二個問題的答案是一樣的,我們可以利用  Clipboard API 來實現復制圖像的問題及解決 document.execCommand API 已被廢棄的問題。

接下來,我們的目標就是實現復制圖像的功能了,因為要利用到 Clipboard API,所以阿寶哥先來介紹一下該 API。

二、Clipboard API 簡介

Clipboard 接口實現了 Clipboard API,如果用戶授予了相應的權限,就能提供系統剪貼板的讀寫訪問。在  Web 應用程序中,Clipboard API 可用于實現剪切、復制和粘貼功能。該 API 用于取代通過 document.execCommand API  來實現剪貼板的操作。

在實際項目中,我們不需要手動創建 Clipboard 對象,而是通過 navigator.clipboard來獲取 Clipboard 對象:

 怎么實現復制圖像

在獲取 Clipboard 對象之后,我們就可以利用該對象提供的 API 來訪問剪貼板,比如:

navigator.clipboard.readText().then(   clipText => document.querySelector(".editor").innerText = clipText);

以上代碼將 HTML 中含有 .editor  類的第一個元素的內容替換為剪貼板的內容。如果剪貼板為空,或者不包含任何文本,則元素的內容將被清空。這是因為在剪貼板為空或者不包含文本時,readText  方法會返回一個空字符串。

在繼續介紹 Clipboard API 之前,我們先來看一下 Navigator API: clipboard 的兼容性:

怎么實現復制圖像

(圖片來源:https://caniuse.com/mdn-api_navigator_clipboard)

異步剪貼板 API 是一個相對較新的 API,瀏覽器仍在逐漸實現它。由于潛在的安全問題和技術復雜性,大多數瀏覽器正在逐步集成這個  API。對于瀏覽器擴展來說,你可以請求 clipboardRead 和 clipboardWrite 權限以使用 clipboard.readText() 和  clipboard.writeText()。

好的,接下來阿寶哥來演示一下如何使用 clipboard 對象提供的 API 來操作剪貼板,以下示例的運行環境是 Chrome  87.0.4280.88。

三、將數據寫入到剪貼板

3.1 writeText()

writeText 方法可以把指定的字符串寫入到系統的剪貼板中,調用該方法后會返回一個 Promise 對象:

<button onclick="copyPageUrl()">拷貝當前頁面地址</button> <script>    async function copyPageUrl() {      try {        await navigator.clipboard.writeText(location.href);        console.log("頁面地址已經被拷貝到剪貼板中");      } catch (err) {        console.error("頁面地址拷貝失敗: ", err);      }   } </script>

對于上述代碼,當用戶點擊 拷貝當前頁面地址 按鈕時,將會把當前的頁面地址拷貝到剪貼板中。

3.2 write()

write 方法除了支持文本數據之外,還支持將圖像數據寫入到剪貼板,調用該方法后會返回一個 Promise 對象。

<button onclick="copyPageUrl()">拷貝當前頁面地址</button> <script>    async function copyPageUrl() {      const text = new Blob([location.href], {type: 'text/plain'});      try {        await navigator.clipboard.write(          new ClipboardItem({            "text/plain": text,          }),        );        console.log("頁面地址已經被拷貝到剪貼板中");      } catch (err) {        console.error("頁面地址拷貝失敗: ", err);      }   } </script>

在以上代碼中,我們先通過 Blob API 創建 Blob 對象,然后使用該 Blob 對象來構造 ClipboardItem 對象,最后再通過  write 方法把數據寫入到剪貼板。介紹完如何將數據寫入到剪貼板,下面我們來介紹如何從剪貼板中讀取數據。

四、從剪貼板中讀取數據

4.1 readText()

readText 方法用于讀取剪貼板中的文本內容,調用該方法后會返回一個 Promise 對象:

<button onclick="getClipboardContents()">讀取剪貼板中的文本</button> <script>    async function getClipboardContents() {      try {        const text = await navigator.clipboard.readText();        console.log("已讀取剪貼板中的內容:", text);      } catch (err) {        console.error("讀取剪貼板內容失敗: ", err);      }    } </script>

對于上述代碼,當用戶點擊 讀取剪貼板中的文本 按鈕時,如果當前剪貼板含有文本內容,則會讀取剪貼板中的文本內容。

4.2 read()

read 方法除了支持讀取文本數據之外,還支持讀取剪貼板中的圖像數據,調用該方法后會返回一個 Promise 對象:

<button onclick="getClipboardContents()">讀取剪貼板中的內容</button> <script> async function getClipboardContents() {   try {     const clipboardItems = await navigator.clipboard.read();     for (const clipboardItem of clipboardItems) {       for (const type of clipboardItem.types) {         const blob = await clipboardItem.getType(type);         console.log("已讀取剪貼板中的內容:", await blob.text());       }     }   } catch (err) {       console.error("讀取剪貼板內容失敗: ", err);     }   } </script>

對于上述代碼,當用戶點擊 讀取剪貼板中的內容 按鈕時,則會開始讀取剪貼板中的內容。到這里 clipboard 對象中涉及的 4 個  API,阿寶哥都已經介紹完了,最后我們來看一下如何實現復制圖像的功能。

五、實現復制圖像的功能

在最后的這個示例中,阿寶哥將跟大家一步步實現復制圖像的核心功能,除了復制圖像之外,還會同時支持復制文本。在看具體代碼前,我們先來看一下實際的效果:

怎么實現復制圖像

在上圖對應的網頁中,我們先點擊 復制 按鈕,則圖像和文本都會被選中。之后,我們在點擊 粘貼  按鈕,則控制臺會輸出從剪貼板中讀取的實際內容。在分析具體的實現方式前,我們先來看一下對應的頁面結構:

<div id="container">    <img src="http://cdn.semlinker.com/abao.png" width="80" height="80" />    <p>大家好,我是阿寶哥</p> </div> <button onclick="writeDataToClipboard()">復制</button> <button onclick="readDataFromClipboard()">粘貼</button>

上面的頁面結構很簡單,下一步我們來逐步分析一下以上功能的實現過程。

5.1 請求剪貼板寫權限

默認情況下,會為當前的激活的頁面自動授予剪貼板的寫入權限。出于安全方面考慮,這里我們還是主動向用戶請求剪貼板的寫入權限:

async function askWritePermission() {   try {     const { state } = await navigator.permissions.query({       name: "clipboard-write",     });       return state === "granted";   } catch (error) {       return false;   } }

5.2 往剪貼板寫入圖像和普通文本數據

要往剪貼板寫入圖像數據,我們就需要使用 navigator.clipboard 對象提供的 write  方法。如果要寫入圖像數據,我們就需要獲取該圖像對應的 Blob 對象,這里我們可以通過 fetch API 從網絡上獲取圖像對應的響應對象并把它轉化成 Blob  對象,具體實現方式如下:

async function createImageBlob(url) {   const response = await fetch(url);   return await response.blob(); }

而對于普通文本來說,只需要使用前面介紹的 Blob API 就可以把普通文本轉換為 Blob 對象:

function createTextBlob(text) {   return new Blob([text], { type: "text/plain" }); }

在創建完圖像和普通文本對應的 Blob 對象之后,我們就可以利用它們來創建 ClipboardItem 對象,然后再調用 write  方法把這些數據寫入到剪貼板中,對應的代碼如下所示:

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("文本和圖像復制成功");         } catch (error) {           console.error("文本和圖像復制失敗", error);         }       }    } }

在以上代碼中,使用了一個 select 方法,該方法用于實現選擇的效果,對應的代碼如下所示:

function select(element) {   const selection = window.getSelection();   const range = document.createRange();   range.selectNodeContents(element);   selection.removeAllRanges();   selection.addRange(range); }

通過 writeDataToClipboard 方法,我們已經把圖像和普通文本數據寫入剪貼板了。下面我們來使用 navigator.clipboard  對象提供的 read 方法,來讀取已寫入的數據。如果你需要讀取剪貼板的數據,則需要向用戶請求 clipboard-read 權限。

5.3 請求剪貼板讀取權限

這里我們定義了一個 askReadPermission 函數來向用戶請求剪貼板讀取權限:

async function askReadPermission() {   try {     const { state } = await navigator.permissions.query({       name: "clipboard-read",     });     return state === "granted";   } catch (error) {     return false;   } }

當調用 askReadPermission 方法后,將會向當前用戶請求剪貼板讀取權限,對應的效果如下圖所示:

怎么實現復制圖像

5.4 讀取剪貼板中已寫入的數據

創建好 askReadPermission 函數,我們就可以利用之前介紹的 navigator.clipboard.read  方法來讀取剪貼板的數據了:

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("已讀取剪貼板中的內容:", await blob.text());           }         }       } catch (err) {          console.error("讀取剪貼板內容失敗: ", err);       }      }    } }

其實,除了點擊 粘貼 按鈕之外,我們還可以通過監聽 paste 事件來讀取剪貼板中的數據。需要注意的是,如果當前的瀏覽器不支持異步 Clipboard  API,我們可以通過 clipboardData.getData 方法來讀取剪貼板中的文本數據:

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('已獲取的文本數據: ', text); });

而對于圖像數據,則可以通過以下方式進行讀取:

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 方法用于實現把復制的圖片插入到當前選區已選擇的區域中,對應的代碼如下:

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); }

感謝各位的閱讀,以上就是“怎么實現復制圖像”的內容了,經過本文的學習后,相信大家對怎么實現復制圖像這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿拉善左旗| 兴和县| 南乐县| 沙河市| 开鲁县| 沙田区| 上饶县| 蕉岭县| 莱阳市| 栾川县| 海晏县| 梓潼县| 大田县| 普格县| 奎屯市| 威宁| 海淀区| 留坝县| 堆龙德庆县| 北川| 潞城市| 咸宁市| 八宿县| 文山县| 疏附县| 大厂| 青田县| 泸定县| 陵川县| 五原县| 濮阳县| 云阳县| 元江| 延寿县| 井陉县| 松原市| 宁武县| 元氏县| 西青区| 东台市| 友谊县|