淘先锋技术网

首页 1 2 3 4 5 6 7

事情是这样的,有一个功能是想实现复制+粘贴图片上传。刚开始觉得这简直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只能监听到这两种的粘贴事件。

如果有更好的方法请赐教!!感激不尽!!

完结!
撒花!