背景

最近做了图片上传和预览的性能,总结了原生js获取本地上传图片的base64编码并读取图片的宽和高的实现办法。

实现

1、成果
假如咱们的文件上传页面构造是这样的:

当咱们点击附件信息处的加号时就会调出图片上传,抉择一张图片进行上传。

图片上传胜利

鼠标悬浮在图片上将呈现放大和删除的图标。

点击放大镜咱们能够预览图片

2、页面标签:
咱们精简一下页面,只留下图片上传及预览所用到的页面标签,如下:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>图片上传</title></head><body>    <!-- 文件上传框区域,咱们只承受图片类型的文件上传 暗藏域-->    <input class="ivu-input-file" type="file" accept="image/gif,image/jpeg,image/jpg,image/png" style="display:none"/>    <!-- 上传文件展现区域 -->    <div class="ivu-img-wrapper">      <!--这里是图片容器-->      <--上传后展现的图片 动态创建标签-->      <img class="ivu-file-img" src="${src}"></img>      <--鼠标悬浮呈现预览和删除按钮图标 动态创建标签-->      <div class="ivu-file-pop">        <img src="${enlarge}" id="ivu-enlarge-${order}"></img>        <img src="${cut}" id="ivu-cut-${order}"></img>      </div>      <!--点击该区域进行图片上传-->          <div class="ivu-annex">          +      </div>    </div>   <--遮罩层 图片预览显示-->    <div class="ivu-pop">        <div class="ivu-pop-wrapper">            <img class="ivu-pop-close" src="${closePop}">            </img>            <img class="ivu-pop-img" src="${down}"></img>        </div>    </div></body><script>   </script></html>

3、js代码
咱们用原生js来实现第一个步骤所形容的成果。
以下代码将增加到上个步骤的<script>标签中
首先咱们给加号绑定事件

  //获取加号元素  let annex = document.querySelector(".ivu-annex"); //绑定点击事件  annex.addEventListener("click", function() {    //拿到暗藏的文件上传域    let fileDomain = document.querySelector(".ivu-input-file");    //触发文件上传域事件    fileDomain.click();  });  

接下来咱们来绑定文件上传域事件

//文件上传域元素let fileInput = document.querySelector(".ivu-input-file");//用来寄存base64图片的数组var fileList = [];//给文件上传域绑定change事件fileInput.addEventListener("change", function() {    //获取寄存图片的容器    let imgWrapper = document.querySelector(".ivu-img-wrapper");    //获取加号元素    let operate = document.querySelector(".ivu-annex");    //获取上传的图片    let file = fileInput.files[0];    //筹备读取图片    if (window.FileReader && file) {     //调用图片读取办法      var reader = new FileReader();     //读取图片      reader.readAsDataURL(file);     //监听图片读取进度      reader.onloadend = function(e) {        //读取胜利,拿到base64编码        let imgBase64 = e.target.result;        //接下来动态创建标签 跟上个步骤页面标签备注中 动态创建标签的地位相响应,以下这些动作均为应用原生js创立了动静的img标签以及动态创建了放大和删除的遮罩层。 可依据本人的我的项目及业务需要自行调整。也能够跳过该局部,间接看图片预览。        let order = fileList.length;        let div = document.createElement("div");        div.className = `ivu-file-annex${order}`;        div.innerHTML = createImg(imgBase64, order);        fileList.push(imgBase64);        imgWrapper.insertBefore(div, operate);        //在这里初始化下图片预览事件        previewImg(imgBase64, order)      };    }

通过以上步骤咱们曾经拿到了base64的图片流,接下来咱们来实现预览性能。

function previewImg (imgBase64, order){    //获取以后图片对应的放大镜元素    let previewImg = document.querySelector(`#ivu-enlarge-${order}`);    //给放大镜绑定事件    previewImg.addEventListener("click", function() {        //申明异步解决promise对象          new Promise(function(resolve, reject) {            //创立一个标签用来加载图片            const image = document.createElement("img");            image.src = imgBase64            //待图片加载实现读取图片的实在宽高。            image.addEventListener("load", function(e) {                resolve({                    imgWidth: e.target.width,                    imgHeight: e.target.height,                });        })        .then(({imgWidth,imgHeight})=>{                //遮罩层                let pop = document.querySelector(".ivu-pop");                //预览图片容器                let wrapper = document.querySelector(".ivu-pop-wrapper");                //预览图片                let imgPop = document.querySelector(".ivu-pop-img");                //base64放入预览图片img标签src                imgPop.src = imgBase64;                //设置容器大小为图片的实在大小                wrapper.style.width = `${imgWidth}px`;                wrapper.style.height = `${imgHeight}px`;                //展现遮罩层 预览图片                pop.style.display = "block";            })  });}

总结

以上就是应用原生js获取本地上传的图片转成base64流并读取到图片的实在宽高进行预览的例子,该文解说了次要思路,具体实现细节还波及到一些款式,大家依照这个思路联合本人的业务需要进行实现。如有疑难,欢送评论区里进行探讨!!