最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript實(shí)現(xiàn)復(fù)制圖片功能的方法示例

 更新時(shí)間:2025年03月14日 08:27:02   作者:程序員小寒  
本文主要介紹了在JavaScript中實(shí)現(xiàn)復(fù)制圖片的方法,先介紹了實(shí)現(xiàn)復(fù)制的前置知識(shí),包括傳統(tǒng)的 execCommand 方法及其優(yōu)缺點(diǎn)和 Clipboard API,然后詳細(xì)闡述了如何將不同形式的圖片轉(zhuǎn)化為blob對(duì)象并通過(guò)Clipboard API實(shí)現(xiàn)復(fù)制,還提及了兼容性問(wèn)題及預(yù)覽、下載圖片的實(shí)現(xiàn)思路

最近開(kāi)發(fā)中遇到一個(gè)需求,就是用戶(hù)希望能通過(guò)直接點(diǎn)擊按鈕復(fù)制圖片,然后就可以很方便的把圖片發(fā)送到班群中,于是就有了復(fù)制圖片的需求。

那么如何通過(guò)JavaScript來(lái)實(shí)現(xiàn)復(fù)制圖片呢?

一、前置知識(shí):如何實(shí)現(xiàn)復(fù)制?

既然要復(fù)制圖片,那我們先看看前端是怎么實(shí)現(xiàn)復(fù)制功能的。

一般來(lái)說(shuō),實(shí)現(xiàn)復(fù)制有2種方案:

  • document.execCommand()方法;
  • Clipboard API

復(fù)制功能的安全限制:復(fù)制腳本需要放在監(jiān)聽(tīng)事件回調(diào)里面進(jìn)行執(zhí)行,由用戶(hù)觸發(fā)(比如點(diǎn)擊事件),如果直接執(zhí)行腳本,瀏覽器可能會(huì)報(bào)錯(cuò)。

下面分別介紹下這2個(gè)方法:

1.1 document.execCommand()

使用方法:

先選中文本,然后調(diào)用 document.execCommand('copy'),即可將選中的文本復(fù)制到剪貼板。

const input = document.getElementById("input");
input.select(); // 注意 input 框不能添加 disabled 屬性,否則會(huì)影響 select() 方法
document.execCommand("copy");

同樣的它還可以實(shí)現(xiàn)剪切粘貼功能。

  • document.execCommand('cut'):剪切選中的文本到剪貼板。
  • document.execCommand('paste'):從剪貼板粘貼文本到光標(biāo)位置。

剪切功能的使用和復(fù)制一樣,所以這里就不做演示了。我這邊再演示一下粘貼功能。

粘貼功能有以下使用限制:

  • 確保元素是可編輯的,比如inputtextarea、contenteditable屬性為true的元素。
  • 確保元素是焦點(diǎn)元素,可以使用focus()方法將焦點(diǎn)設(shè)置到元素上。
const target = document.getElementById('pasteTargetInput');
target.focus(); // 確保目標(biāo)元素獲得焦點(diǎn)
document.execCommand('paste'); // 嘗試粘貼

但是現(xiàn)代瀏覽器比如(Chrome、Firefox、Edge)已經(jīng)限制或廢棄了 execCommand("paste") 的直接使用,所以不推薦用這個(gè)api了。

最后總結(jié)一下,document.execCommand()是實(shí)現(xiàn)復(fù)制的一個(gè)傳統(tǒng)方法,它的優(yōu)缺點(diǎn)如下:

  • 優(yōu)點(diǎn):低版本瀏覽器兼容性好,
  • 缺點(diǎn):
  • 已被web 標(biāo)準(zhǔn)棄用,不推薦使用。
  • 只能復(fù)制文本,不能復(fù)制圖片或者二進(jìn)制數(shù)據(jù)。
  • 只能講選中的內(nèi)容寫(xiě)入到剪貼板,不能直接寫(xiě)入自定義內(nèi)容。
  • 它是同步操作,如果復(fù)制內(nèi)容過(guò)多,會(huì)引起頁(yè)面卡頓。

1.2 Clipboard API

在瀏覽器的BOM對(duì)象中,有一個(gè)APIclipboard,它提供了系統(tǒng)剪貼板的讀寫(xiě)訪(fǎng)問(wèn)能力,可以實(shí)現(xiàn)剪切、復(fù)制和粘貼功能,我們可以通過(guò)window上的navigator對(duì)象直接訪(fǎng)問(wèn)到一個(gè)clipboard對(duì)象。

console.log(navigator.clipboard);

clipboard提供了四個(gè)方法:

  • read():從剪切板讀取數(shù)據(jù),它會(huì)返回一個(gè)Promise,并將數(shù)據(jù)包裝成一個(gè)ClipboardItem對(duì)象回傳,
  • readText():從剪切板中讀取文本,它會(huì)返回一個(gè)Promise對(duì)象,并將剪切板數(shù)據(jù)作為String回傳,
  • write():寫(xiě)入數(shù)據(jù)(ClipboardItem對(duì)象)到剪切板,它會(huì)返回一個(gè)Promise,Promise成功意味著寫(xiě)入完成,
  • writeText():寫(xiě)入文本到剪切板,它會(huì)返回一個(gè)Promise,Promise成功意味著寫(xiě)入完成。

我們可以通過(guò)上面描述的write()writeText()方法實(shí)現(xiàn)復(fù)制功能,writeText()只能寫(xiě)入文本,而write()方法則可以寫(xiě)入任意數(shù)據(jù),所以我們需要使用write()方法實(shí)現(xiàn)復(fù)制圖片的功能。

二、實(shí)現(xiàn)復(fù)制圖片

一般圖片是通過(guò)兩種形式加載:

  • 遠(yuǎn)程URL,最常見(jiàn)的是cdn 地址,比如https://cdn.xxx.cn/example.png
  • base64 URL,一些體積較小的圖片通常會(huì)打包成base64字符串,以減少網(wǎng)站資源請(qǐng)求數(shù)量,比如data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...

不管是什么圖片形式的圖片,我們最終目的都是需要將它轉(zhuǎn)化為blob對(duì)象,然后通過(guò)navigator.clipboard.write()方法寫(xiě)入到剪貼板。

比如這樣一張圖片:

<img src="https://xxx" alt="加載失敗" id="img"/>

我們可以通過(guò) canvas 將圖片復(fù)制到剪貼板,具體代碼如下:

function copyImage(img) {
  const canvas = document.createElement('canvas')
  canvas.width = img.width
  canvas.height = img.height
  const ctx = canvas.getContext('2d')
  ctx.drawImage(img, 0, 0, img.width, img.height)
  canvas.toBlob((blob) => {
    // 目前圖片只支持 png 類(lèi)型
    const clipboardItem = new ClipboardItem({ 'image/png': blob })
    navigator.clipboard.write([clipboardItem])
  })
}
img.addEventListener("click", () => {
  copyImage(img);
});

這里如果出現(xiàn)Uncaught SecurityError: Failed to execute 'toBlob' on 'HTMLCanvasElement'報(bào)錯(cuò),可能是你使用的圖片跨域了,首先確保圖片資源服務(wù)器允許跨域使用,然后需要在img標(biāo)簽上增加crossOrigin屬性。

<img src="xxx" crossOrigin/>

當(dāng)然實(shí)際業(yè)務(wù)中可能提供的只是一個(gè)圖片點(diǎn)擊后的跳轉(zhuǎn)鏈接,需要先把鏈接轉(zhuǎn)成一張二維碼圖片,再進(jìn)行復(fù)制。

這里使用第三方庫(kù)qrcode,把鏈接轉(zhuǎn)化成二維碼。

import QRcode from 'qrcode';

async function copyImage(url) {
  // 轉(zhuǎn)成 base64 的 url
   const url = await QRcode.toDataURL(link, {
      errorCorrectionLevel: 'H', // 糾錯(cuò)級(jí)別最高
      width: 128,
      margin: 2,
      scale: 1,
    });
    const blob = await (await fetch(url)).blob();
    const clipboardItem = new ClipboardItem({ 'image/png': blob })
    navigator.clipboard.write([clipboardItem])
}

我們這里通過(guò)QRcode.toDataURL()方法,拿到二維碼的base64圖片url,然后通過(guò)原生的fetch方法,把二維碼圖片轉(zhuǎn)化成blob對(duì)象,最后以ClipboardItem形式寫(xiě)入到clipboard中。

除了fetch以外,還可以通過(guò)如下方式將base64圖片轉(zhuǎn)化為blob對(duì)象,具體代碼如下:

function dataURIToBlob(dataURI) {
    const base64Index = dataURI.indexOf(';base64,') + 8;
    const base64 = dataURI.substring(base64Index);
    const byteCharacters = atob(base64);
    const byteArrays = [];

    for (let i = 0; i < byteCharacters.length; i++) {
      byteArrays.push(byteCharacters.charCodeAt(i));
    }

    const byteArray = new Uint8Array(byteArrays);
    const blob = new Blob([byteArray], { type: 'image/png' });
    return blob;
}

三、clipboard兼容性問(wèn)題

在一些瀏覽器上可能不支持Clipboard API,所以需要通過(guò)navigator.clipboard的值是否為undefined判斷此瀏覽器是否支持復(fù)制功能,如果不支持Clipboard API的話(huà),就無(wú)法復(fù)制圖片了,這時(shí)候可以使用document.execCommand('copy')來(lái)復(fù)制文本,或者直接給用戶(hù)提示該瀏覽器不支持復(fù)制圖片。

 // 將dataBase64復(fù)制到剪切板
function copyToClipboard(text) {
  let a = document.createElement('input');
  a.value = text;
  document.body.appendChild(a);
  a.select();
  document.execCommand('copy');
  a.remove();
}

function copyImage() {
  if (navigator.clipboard) {
     //...
      const clipboardItem = new ClipboardItem({ 'image/png': imgBlob });
      navigator.clipboard.write([clipboardItem]);
      console.log('復(fù)制成功');
  } else {
    copyToClipboard(img.src);
  }
}

四、其它功能

4.1 預(yù)覽圖片

預(yù)覽圖片主要依賴(lài)于URL.createObjectURL這個(gè)原生API,具體代碼如下:

function previewImage(img) {
  const url = URL.createObjectURL(blob);
  const img = document.createElement('img');
  img.src = url;
  document.body.appendChild(img);
}

4.2 下載圖片

下載圖片主要依賴(lài)于a標(biāo)簽的download屬性,具體代碼如下:

function downloadImage(img) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = true;
  a.click();
  URL.revokeObjectURL(url);
  console.log('下載圖片成功');
}

五、小結(jié)

本文主要介紹了前端如何實(shí)現(xiàn)復(fù)制圖片的功能,核心是通過(guò)Clipboard API來(lái)實(shí)現(xiàn)的,如遇到瀏覽器兼容問(wèn)題,可以考慮回退使用document.execCommand()進(jìn)行低版本的兼容,另外還介紹了預(yù)覽圖片下載圖片的實(shí)現(xiàn)思路,希望能幫助到大家!

以上就是JavaScript實(shí)現(xiàn)復(fù)制圖片功能的方法示例的詳細(xì)內(nèi)容,更多關(guān)于JavaScript復(fù)制圖片功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js異步加載的三種解決方案

    js異步加載的三種解決方案

    默認(rèn)情況javascript是同步加載的,javascript的加載時(shí)阻塞的,后面的元素要等待javascript加載完畢后才能進(jìn)行再加載,如何解決這個(gè)問(wèn)題呢,接下來(lái)將為你詳細(xì)介紹下異步加載js三種實(shí)現(xiàn)方案,感興趣的你可以參考下哈
    2013-03-03
  • JavaScript中 ES6變量的結(jié)構(gòu)賦值

    JavaScript中 ES6變量的結(jié)構(gòu)賦值

    這篇文章主要介紹了JS 中ES6變量的結(jié)構(gòu)賦值的相關(guān)資料,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • JavaScript遍歷對(duì)象的五種常用方式總結(jié)

    JavaScript遍歷對(duì)象的五種常用方式總結(jié)

    這篇文章主要介紹了JavaScript遍歷對(duì)象的五種常用方式,分別是for...in、Object.keys()+forEach()、Object.values()+forEach()、Object.entries()+forEach()和for...of+Object.entries(),文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2025-05-05
  • layui: layer.open加載窗體時(shí)出現(xiàn)遮罩層的解決方法

    layui: layer.open加載窗體時(shí)出現(xiàn)遮罩層的解決方法

    今天小編就為大家分享一篇layui: layer.open加載窗體時(shí)出現(xiàn)遮罩層的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • laydate 顯示結(jié)束時(shí)間不小于開(kāi)始時(shí)間的實(shí)例

    laydate 顯示結(jié)束時(shí)間不小于開(kāi)始時(shí)間的實(shí)例

    下面小編就為大家?guī)?lái)一篇laydate 顯示結(jié)束時(shí)間不小于開(kāi)始時(shí)間的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • js面向?qū)ο蟮膶?xiě)法

    js面向?qū)ο蟮膶?xiě)法

    這篇文章主要介紹了四種js面向?qū)ο蟮某R?jiàn)寫(xiě)法,還介紹了有關(guān)this的相關(guān)內(nèi)容,感興趣的小伙伴們可以參考一下
    2016-02-02
  • BootStrap Table 后臺(tái)數(shù)據(jù)綁定、特殊列處理、排序功能

    BootStrap Table 后臺(tái)數(shù)據(jù)綁定、特殊列處理、排序功能

    本節(jié)主要介紹Bootstrap的后臺(tái)數(shù)據(jù)綁定、特殊列處理及列的排序功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧
    2017-05-05
  • JavaScript實(shí)現(xiàn)的in_array函數(shù)

    JavaScript實(shí)現(xiàn)的in_array函數(shù)

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)的in_array函數(shù),用于判斷一個(gè)值是否在數(shù)組中,類(lèi)似PHP的in_array函數(shù),需要的朋友可以參考下
    2014-08-08
  • 微信小程序組件化開(kāi)發(fā)的實(shí)戰(zhàn)步驟

    微信小程序組件化開(kāi)發(fā)的實(shí)戰(zhàn)步驟

    雖然小程序在剛推出時(shí)是不支持組件化的,但如今小程序開(kāi)始支持自定義組件開(kāi)發(fā),下面這篇文章主要給大家介紹了關(guān)于微信小程序組件化開(kāi)發(fā)的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • 淺析對(duì)JS中方法unshift和push方法的理解

    淺析對(duì)JS中方法unshift和push方法的理解

    JavaScript中的`unshift`和`push`方法用于在數(shù)組的開(kāi)始和結(jié)尾添加元素,它們會(huì)直接修改原數(shù)組并返回新的數(shù)組長(zhǎng)度,本文介紹JS中方法unshift和push方法的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2024-12-12

最新評(píng)論

罗城| 建瓯市| 恩施市| 嘉兴市| 沂源县| 观塘区| 保定市| 竹山县| 洪湖市| 莒南县| 巫山县| 高州市| 都昌县| 常山县| 常德市| 商丘市| 吴川市| 建昌县| 莒南县| 阿拉善右旗| 库伦旗| 尉犁县| 汕头市| 广灵县| 岐山县| 瑞安市| 无棣县| 长葛市| 冀州市| 惠州市| 准格尔旗| 安西县| 镇远县| 义乌市| 民勤县| 大埔区| 衢州市| 扶绥县| 十堰市| 墨竹工卡县| 南昌县|