实现多图片复制到粘贴板

218 阅读1分钟

navigator.clipboard.write

优点:浏览器兼容情况好,支持图片、文本复制,官方推荐的api
缺点:不支持多个图片复制,for循环写入会覆盖
(ps: 网上有查到用setTimeout包裹 API, 可解决覆盖问题,我用的并不生效)

export const copyImagesToClipboard = async (imageUrls: string[]) => {
    const clipboardItems = [];
  
    for (let i = 0; i < imageUrls.length; i++) {
      const imageUrl = imageUrls[i];
      const response = await fetch(imageUrl);
      const blob = await response.blob();
      const image = new Blob([blob], { type: 'image/png' });
      const clipboardItem = new ClipboardItem({
        ['image/png']: image
      });
      // clipboardItems.push(clipboardItem);
      navigator.clipboard
      .write([clipboardItem])
      .then((res) => {
        console.log(res, 'res');
        message.success('复制成功');
      })
      .catch((err) => {
        console.log(err, 'err');
        message.error('复制失败');
      });
    }
  };

document.execCommand('copy')

优点: 支持多个图片复制
缺点: 已经不推荐使用啦,复制到文本必须被选中

/** 多图复制 */
export const copyImagesToClipboard = (images: string[]) => {
  const selection = window.getSelection();
  const range = document.createRange();
  // 创建一个容器,用于存储图片
  const imgContarin = document.createElement('div');
  imgContarin.style.width = '0px';
  imgContarin.style.height = '0px';
  // 元素不展示在文档中会导致复制失败,不能设置display: none
  imgContarin.style.overflow = 'hidden';
  // 先清除剪贴板内容
  selection?.removeAllRanges();

  for (let i = 0; i < images.length; i++) {
    const url = images[i];
    const imgNode = document.createElement('img');
    imgNode.src = url;
    // 图片再添加到容器中
    imgContarin.appendChild(imgNode);
  }
  // 追加到文档中
  document.body.appendChild(imgContarin);
  // 设置范围的起始位置为第一张图片的起始位置
  range.setStartBefore(imgContarin.childNodes[0]);
  // 设置范围的结束位置为最后一张图片的结束位置
  range.setEndAfter(imgContarin.childNodes[images.length - 1]);
  if (!document.queryCommandSupported('copy')) return '浏览器暂不支持复制命令';
  selection && selection.addRange(range);

  document.execCommand('copy');
  selection && selection.removeAllRanges();
  document.body.removeChild(imgContarin);
};