🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
一、获取剪切板的图片(拿到 File 对象)
js粘贴事件paste简单解析及遇到的坑 - 云+社区 - 腾讯云 (tencent.com)
document.addEventListener('paste', function(event) {let items = event.clipboardData && event.clipboardData.items;let file: any = null;if (items && items.length) {// 检索剪切板itemsfor (var i = 0; i < items.length; i++) {if (items[i].type.indexOf('image') !== -1) {file = items[i].getAsFile();break;}}}fileByBase64(file, (base64) => {shotCallback(base64);});console.log('file', file);// 此时file就是剪切板中的图片文件 });
本来想直接获取这个对象的,然鹅这个 clipboardData 对象只存在于 ClipboardEvent 事件中,只能在事件(这里是 parse 事件)触发的时候才能拿到。
ClipboardEvent.clipboardData - Web API 接口参考 | MDN (mozilla.org)
题外话:可以直接用 navigator.clipboard 获取到剪切板内容(拿到 Blob 对象)
Navigator.clipboard - Web API 接口参考 | MDN (mozilla.org)
剪贴板操作 Clipboard API 教程 - 阮一峰的网络日志 (ruanyifeng.com)
const getClipboard = async () => {const clipboardItems = await navigator.clipboard.read();for (const clipboardItem of clipboardItems) {for (const type of clipboardItem.types) {const blob = await clipboardItem.getType(type);console.log(URL.createObjectURL(blob));}} };
二、File 对象转 Base64(利用 FileReader)
const fileByBase64 = (file, callback) => {const reader = new FileReader();// 传入一个参数对象即可得到基于该参数对象的文本内容reader.readAsDataURL(file);reader.onload = function(e: any) {// target.result 该属性表示目标对象的 DataURLconsole.log(e.target.result);callback(e.target.result);}; };
题外话 canvas -> dataUrl(Base64)
才发现 Base64 是 DataUrl 的编码,可以理解为一种东西吧。
canvas 对象可以直接转变成 base64,有一个很常用的 api:
const dataURL = canvas.toDataURL();
三、Base64 转 Blob
const base64ByBlob = (base64, callback) => {let arr = base64.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}console.log(new Blob([u8arr], { type: mime }));callback(new Blob([u8arr], { type: mime })); };
题外话:Blob -> Base64(利用 FileReader)
由于 File 是特殊类型的 Blob,所以跟 File -> Base64 是一样的。
function blobToDataURI(blob, callback) {var reader = new FileReader();reader.onload = function (e) {callback(e.target?.result);};reader.readAsDataURL(blob); }
题外话:File <--> Blob
它俩可以用构造函数直接相互转换,没有中间商 Base64。不过 file -> blob 会丢失 filename。
const blob = new Blob([file], {type: file.type }
const file = new File([blob], filename, {type: blob.type });
四、blob 转 url、file 转 url
const url1 = window.URL.createObjectURL(blob); const url2 = window.URL.createObjectURL(file);
这里的 file 会被当做 blob 对象来使用,毕竟 file 是特殊的 blob,所以输出结果都是:
blob:http://localhost:3000/1df14e9d-b9d3-43d5-87ff-2f7c0ae44a9d
这种由 blob:http:// 开头的路径。
题外话:url -> blob
const urlToBlob = () => {fetch(url).then((res) => res.blob()).then((blob) => console.log(blob)); };
五、url 变 Image
const img = new Image(); img.src = url;
综合应用:获取剪切板图片并转成 Base64,然后 Base64 转成 Blob,然后 Blob 转成 url,然后转成图片 append 到 body 上
document.addEventListener('paste', function(event) {let items = event.clipboardData && event.clipboardData.items;console.log('items', items);let file: any = null;if (items && items.length) {// 检索剪切板 itemsfor (var i = 0; i < items.length; i++) {if (items[i].type.indexOf('image') !== -1) {// 此时file就是剪切板中的图片文件file = items[i].getAsFile();break;}}}fileByBase64(file, base64 => {base64ByBlob(base64, (blob) => {const url = window.URL.createObjectURL(blob);console.log('url', url);const img = new Image();img.src = url;img.onload = () => {document.body.appendChild(img);};});}); });
如果不需要额外使用 Base64 的话,直接用 file 对象替代 blob 也是可以的,因为 file 只是特殊的 blob,大家都是二进制文件:
document.addEventListener('paste', function(event) {let items = event.clipboardData && event.clipboardData.items;console.log('items', items);let file: any = null;if (items && items.length) {// 检索剪切板 itemsfor (var i = 0; i < items.length; i++) {if (items[i].type.indexOf('image') !== -1) {// 此时file就是剪切板中的图片文件file = items[i].getAsFile();break;}}}const url = window.URL.createObjectURL(file);console.log('url', url);const img = new Image();img.src = url;img.onload = () => {document.body.appendChild(img);}; });
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。