事情是这样的,有一个功能是想实现复制+粘贴图片上传。刚开始觉得这简直so easy啊!但往往现实是很骨感的,开发过程中发现windows系统文件是粘贴的不了的,网上查阅了很多也没有解决的办法。所以提前说好啊,只能粘贴截图和网页上右键1复制的图片。想要粘贴系统文件可以关了。不过您要是能粘贴系统文件麻烦请赐教,感激不尽https://blog.csdn.net/ajujuju/article/details/108119458
话不多少,整吧!
说下思路
监听粘贴事件,然后调用element的文件上传组件的上传方法。其实就想用现成的。如果自己写一个上传也不费劲,就监听到复制的文件就行了,然后调用自己上传的方法。
先来张截图
html代码
这里边有一个 <div id="tar_box" contenteditable=""></div>
这个必须写上,不然ie不好使。IE就是必须监听一个输入框或者可编辑的组件才可以
```html
<template>
<div class="home" @click="resetColor()" v-loading="loading">
<div class="up-bg" @click.stop="setColor" :style="{'borderColor':color}">
<div id="tar_box" contenteditable=""></div>
<div>
<el-upload
ref="upload"
class="upload-demo"
:on-success="handleAvatarSuccess"
action="上传地址"
:before-upload="beforeUpload"
:show-file-list="false"
multiple
>
<el-button size="small" type="text" style="font-size: 14px;padding-bottom: 14px;">点击上传</el-button>
</el-upload>
</div>
</div>
<div style="height: 200px;background: red" contenteditable=''></div>
<div class="imgList">
<div v-for="(item,index) in imgList" class="img-item">
<i class="el-icon-circle-close delete-icon" @click="deletePic(index)"></i>
<img :src="item.fullUrl" >
</div>
</div>
</div>
</template>
js部分
这部分是监听复制粘贴事件
我写在了mounted里面。里边具体的实现也是百度的,忘了在哪看的了,等找到了上链接
找到了:
添加链接描述
mounted() {
let _this = this;
document.addEventListener('paste', function (event) {
let isChrome = false;
if (event.clipboardData || event.originalEvent) {
//not for ie11 某些chrome版本使用的是event.originalEvent
let clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
if (clipboardData.items) {
// for chrome
let items = clipboardData.items,
len = items.length,
blob = null;
isChrome = true;
//items.length比较有意思,初步判断是根据mime类型来的,即有几种mime类型,长度就是几(待验证)
//如果粘贴纯文本,那么len=1,如果粘贴网页图片,len=2, items[0].type = 'text/plain', items[1].type = 'image/*'
//如果使用截图工具粘贴图片,len=1, items[0].type = 'image/png'
//如果粘贴纯文本+HTML,len=2, items[0].type = 'text/plain', items[1].type = 'text/html'
//阻止默认行为即不让剪贴板内容在div中显示出来
event.preventDefault();
//在items里找粘贴的image,据上面分析,需要循环
for (let i = 0; i < len; i++) {
if (items[i].type.indexOf("image") !== -1) {
blob = items[i].getAsFile();
}
}
if (blob !== null) {
let reader = new FileReader();
reader.onload = function (event) {
// event.target.result 即为图片的Base64编码字符串
let base64_str = event.target.result
//可以在这里写上传逻辑 直接将base64编码的字符串上传(可以尝试传入blob对象,看看后台程序能否解析)
_this.uploadImgFromPaste(base64_str, 'paste', isChrome);
}
reader.readAsDataURL(blob);
}
} else {
//for firefox
setTimeout(function () {
//设置setTimeout的原因是为了保证图片先插入到div里,然后去获取值
let imgList = document.querySelectorAll('#tar_box img'),
len = imgList.length,
src_str = '',
i;
for (i = 0; i < len; i++) {
if (imgList[i].className !== 'my_img') {
//如果是截图那么src_str就是base64 如果是复制的其他网页图片那么src_str就是此图片在别人服务器的地址
src_str = imgList[i].src;
}
}
_this.uploadImgFromPaste(src_str, 'paste', isChrome);
}, 1);
}
} else {
//for ie11
setTimeout(function () {
let imgList = document.querySelectorAll('#tar_box img'),
len = imgList.length,
src_str = '',
i;
for (i = 0; i < len; i++) {
if (imgList[i].className !== 'my_img') {
src_str = imgList[i].src;
}
}
//调用上传方法
_this.uploadImgFromPaste(src_str, 'paste', isChrome);
}, 1);
}
})
},
//关键的三个方法
/**调用element的上传方法 需要把base64转换成file上传**/
uploadImgFromPaste(file, type, isChrome) {
let a=this.dataURLtoBlob(file);
let b=this.blobToFile(a);
const upload = this.$refs.upload
upload.handleStart(b);
setTimeout(()=>{
upload.submit();
this.loading=true;
})
},
/**
* 将base64转换为blob
*/
dataURLtoBlob (dataurl) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
},
/**
* 将blob转换为file
*/
blobToFile (theBlob, fileName = 'ocr1.jpeg') {
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
},
这两个是上传前的验证和上传成功后的处理。
//上传前
beforeUpload(file){
this.loading = true;
//这里我写了一个公共的校验方法,这个自定义吧
if (!beforeUploadImage(this, file)) {
this.$message.error("上传图片只能是 JPG、PNG、GIF 格式!上传图片大小不能超过 5MB!");
this.loading = false;
}
return beforeUploadImage(this, file)
},
//上传成功,这里把可编辑组件里的内容清空了
handleAvatarSuccess(res) {
this.loading=false;
document.getElementById('tar_box').innerHTML='';
if (res.status==0){
this.imgList.push(res.data)
}
},
以上的就是全部了。需要注意的地方就是如果适配的时ie浏览器那就必须得写一个输入框或者是一个可编辑的组件。因为ie只能监听到这两种的粘贴事件。
如果有更好的方法请赐教!!感激不尽!!
完结!
撒花!