这篇文章主要讲解了“怎么实现复制图像”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现复制图像”吧!
创新互联建站10多年成都企业网站建设服务;为您提供网站建设,网站制作,网页设计及高端网站定制服务,成都企业网站建设及推广,对柔性防护网等多个方面拥有多年的网站设计经验的网站建设公司。
在写了 这个 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 结构:
![]()
大家好,我是阿宝哥
上面的页面结构很简单,下一步我们来逐步分析一下以上功能的实现过程。
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); }
感谢各位的阅读,以上就是“怎么实现复制图像”的内容了,经过本文的学习后,相信大家对怎么实现复制图像这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!