建设外贸网站的细节,硬件开发入门,济南国迅网站建设公司怎么样,网站模板免费下载酒店管理系统目录 1#xff0c;需求最终效果 2#xff0c;实现示例 3#xff0c;注意点1#xff0c;只支持安全上下文环境2#xff0c;只能读取当前页面的剪切板3#xff0c;权限获取问题4#xff0c;获取内容的 MIME_TYPE 问题1#xff0c;文本内容2#xff0c;图片内容 5#x… 目录 1需求最终效果 2实现示例 3注意点1只支持安全上下文环境2只能读取当前页面的剪切板3权限获取问题4获取内容的 MIME_TYPE 问题1文本内容2图片内容 5只能获取剪切板内容的 blob 类型6URL.revokeObjectURL 的时机 4其他paste 事件简单举例 1需求
一个问题咨询表单页可以上传图片。因为有截图的场景所以需要得先截图保存在本地再上传比较繁琐。
想从剪切板获取截图后直接上传。
最终效果 2实现
从剪切板获取的内容分为文本和非文本分别对应2个API
navigator.clipboard.readText()navigator.clipboard.read()可以用它来获取图片。
获取的内容是 ClipboardItem 对象。
示例
完整代码
templatediv refrefPasteBox/divbutton clickgetClipImg获取剪切板图片/button
/templatescript setup langts
import { ref } from vue;const refPasteBox refHTMLDivElement();
const getClipImg async () {try {const clipboardContent await navigator.clipboard.read();const clipboardItem clipboardContent[0];let noImg true;for (const type of clipboardItem.types) {if (type image/png) {noImg false;const blob await clipboardItem.getType(type);const url URL.createObjectURL(blob);// 如果需要 File 对象const file new File([blob], clipboard-image.png, { type });console.log(file);const img document.createElement(img);img.src url;img.width 300;img.onload () {URL.revokeObjectURL(img.src);};refPasteBox.value?.appendChild(img);}}if (noImg) {alert(当前剪切板中没有图片。\n Windows 系统可通过快捷键\n ⌘V \n查看剪切板);}} catch (err: any) {if (err.name NotAllowedError) {console.log(用户拒绝了访问剪贴板);} else {console.error(无法读取剪贴板内容: , err);}}
};
/script3注意点
1只支持安全上下文环境
安全上下文可以简单理解为只支持 https 协议和本地 http://127.0.0.1、http://localhost。
在 http 环境下是 undefined 2只能读取当前页面的剪切板
有5个区域
页面内容显示区域地址栏书签栏控制台其他应用 在执行 await navigator.clipboard.read() 相关 API 时必须聚焦到区域1否则会有如下报错 正常情况下通过按钮点击来执行 API 时都是满足的。 如果想在控制台中简单测试可以用计时器。在控制台执行后迅速点击页面区域就可以正常执行。
setTimeout(async () {const clipboardContent await navigator.clipboard.read();console.log(clipboardContent);
}, 2000);3权限获取问题
当第一次请求剪切板【读权限】时也就是执行 await navigator.clipboard.read() 时会弹出确认弹窗 允许后就可以正常使用了。如果禁止了无法通过再次执行代码打开该弹窗只能手动重置权限。 4获取内容的 MIME_TYPE 问题
const getClipImg async () {try {const clipboardContent await navigator.clipboard.read();const clipboardItem clipboardContent[0];console.log(clipboardItem);for (const type of clipboardItem.types) {if (type image/png) {const blob await clipboardItem.getType(type);}}} catch (err) {console.log(err)}
};示例代码中通过 for 循环获取了剪切板内容的 type它有几个特点
1文本内容
无论是从什么地方手动复制的文本type 都是2个text/plain 和 text/html。 2图片内容
1如果是截图type 统一为 image/png。 2如果是从网页上复制的图片无论原图片是什么格式type 统一都是2个text/html 和 image/png。 所以只需要判断 MIME 类型为 image/png 即可获取对应的图片。 另外从本地复制的文件图片excel等 无法通过 await navigator.clipboard.read() API 获取。 5只能获取剪切板内容的 blob 类型
// ...
for (const type of clipboardItem.types) {if (type image/png) {const blob await clipboardItem.getType(type);}
}通过 getType 可以获取剪切板的内容结果为 blob 类型
如果需要预览需要转换为 url。
const url URL.createObjectURL(blob);如果需要 File 对象比如上传需要手动转换。
const file new File([blob], clipboard-image.png, { type });6URL.revokeObjectURL 的时机
if (type image/png) {const blob await clipboardItem.getType(type);const url URL.createObjectURL(blob);const img document.createElement(img);img.src url;img.width 300;img.onload () {URL.revokeObjectURL(img.src);};document.body.appendChild(img);
}当通过 URL.createObjectURL() 创建可用于预览的对象 url 后不能通过 URL.revokeObjectURL 立即释放该对象否则图片无法显示。需要等到图片加载完成才行或者不释放问题也不大。
4其他
剪切板 API 获取的内容和 paste 事件得到的内容是有区别的。 paste 事件一般用于富文本编辑粘贴各种类型的文件。 剪切板不能获取本地复制的文件paste 事件可以。MIME 类型问题从网页复制的是 type/html但却可以获取 File 对象。为了兼容应该用 event.clipboardData?.files[0] 并加判断而不是 items[0].getAsFile() getAsFile-参考。获取的 DataTransfer 对象虽然 MDN 上的解释是拖动获取的内容但其实也是粘贴事件获取的内容。
paste 事件简单举例
注意ClipboardEvent 对象中部分内容通过 console.log 是看不到输出的类似打印 currentTarget 得到的是 null但是可以使用的。
templatediv refrefClipBox classclip-box pastegetPasteImage contenteditabletrue/div
/templatescript setup langts
import { ref } from vue;const refClipBox refHTMLDivElement();
function getPasteImage(event: ClipboardEvent) {event.preventDefault();console.log(event);// 检查剪贴板项目const items event.clipboardData?.items || [];if (items[0].type.indexOf(image) 0 || items[0].type text/html) {// const blob items[0].getAsFile();const blob event.clipboardData?.files[0];const url URL.createObjectURL(blob);const img document.createElement(img);img.src url;img.width 300;img.onload () {URL.revokeObjectURL(img.src);};refClipBox.value?.appendChild(img);} else {console.log(不是图片);}
}
/script
style
.clip-box {width: 300px;height: 300px;border: 1px solid #000;
}
/style以上。
参考