Clipboard 实现点击复制一张图片

332 阅读3分钟

我正在参加「掘金·启航计划」

需求,之前写了一个点击下载图片的功能,老板问我能不能改成点击复制,把图片复制出来,经过我反复的拉扯,最终决定不做了,啊哈哈,但是这个需求还是想了解一下怎么实现。于是它来了。

异步 Clipboard API

Clipboard 只能在安全上下文: 此项功能仅在一些支持的浏览器(HTTPS)中可用。但是它也可以在 localhost 下使用哦!。

还有一件事,Clipboard 在正是环境下是需要浏览器授权操作的。如果用户授予了相应的权限,其就能提供系统剪贴板的读写访问能力。在 Web 应用程序中,Clipboard API 可用于实现剪切、复制和粘贴功能。写入剪贴板,脚本可以自动完成,但是读取剪贴板时,浏览器会弹出一个对话框,询问用户是否同意读取。

还还还有一件事,Clipboard API作为下一代的剪贴板操作方法,比传统的document.execCommand()方法更强大、更合理。但是它的兼容性不是太好,有些完全支持,有些部分支持,有些完全不支持(IE)。

使用

所有 Clipboard API 的方法都是异步的;它们返回一个 Promise对象,在剪贴板访问完成后被兑现。因为是异步操作,所以就可很好的解决Document.execCommand()的问题。

Clipboard.readText()

从操作系统的粘贴板读取文本;返回一个 Promise,在从剪切板中检索到文本后,promise 将兑现一个包含剪切板文本数据的DOMString。

async (e) => {
    const text = await navigator.clipboard.readText();
    console.log(text); // 考虑兼容性,也可以使用try catch。
 }

Clipboard.read()

从剪贴板读取数据(比如图片),返回一个 Promise 对象。在检索到数据后,promise 将兑现一个 ClipboardItem 对象的数组来提供剪切板数据。

ClipboardItem 它使开发人员能够轻松地处理不同范围的文件类型和数据。以MIME 类型作为键和Blob为值。 属性: types 返回一个数组,包括可用的 MIME 类型。 方法:getType(type) 方法用于读取剪贴项的数据,返回一个 Promise 对象。该方法接受剪贴项的 MIME 类型作为参数,返回该类型的数据,该参数是必需的,否则会报错。

async function getClipboardContents() {
  try {
    const clipboardItems = await navigator.clipboard.read(); // 返回一个ClipboardItem 组成的数值
    for (const clipboardItem of clipboardItems) { // 取出每个clipboardItem
      for (const type of clipboardItem.types) { // 取出所支持的MIME 类型
        const blob = await clipboardItem.getType(type); // 调用getType 方法获取内容
        console.log(URL.createObjectURL(blob)); // 将blob文件 创建一个暂时链接出来。如果是个图片就可以直接复制给 src。
      }
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
}

Clipboard.write()

写入任意数据至操作系统剪贴板。这是一个异步操作,在操作完成后,返回的 promise 的将被兑现。

图片复制的实现

async (url) =>{
  try {
    const imgURL = url  // 注意谷歌里只支持png
    const data = await fetch(imgURL); // 获取图片的数据
    const blob = await data.blob(); // 转为blob类型
    await navigator.clipboard.write([ // 调用写入方法
      new ClipboardItem({ // 创建一个 ClipboardItem
        [blob.type]: blob 
      })
    ]);
    console.log('Image copied.');
  } catch (err) {
    console.error(err.name, err.message);
  }
}

// 文本的复制

function setClipboard(text) {
  let data = new DataTransfer(); // 这里也可以使用 ClipboardItem去写入文本

  data.items.add("text/plain", text);
  navigator.clipboard.write(data).then(function() {
    /* success */
  }, function() {
    /* failure */
  });
}

Clipboard.writeText()

写入文本至操作系统剪贴板。返回一个 Promise,在文本被完全写入剪切板后,返回的 promise 将被兑现。

await navigator.clipboard.writeText('Yo')