前端文件上传时显示缩略图

在前端开发中,生成需要上传文件的url的方式主要有两种,分别是FileReader.readAsDataURL()URL.createObjectURL()
下面我将以input元素添加文件的方式演示这两种方法的使用。

FileReader.readAsDataURL()

readAsDataURL方法会读取指定的 BlobFile 对象。读取操作完成的时候,触发 loadend 事件,同时result属性将包含一个URL 格式的字符串(base64 编码)以表示所读取文件的内容。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
</head>
<body>
<input id="input" type="file">
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
  window.onload=function () {
      let input=document.getElementById('input');
      let img=document.getElementById('img');
      input.addEventListener('change',function (e) {
          //以下两种写法都能获取到file对象,第一种可以避免this指向产生的影响,比如vue的事件处理函数
          let file=e.target.files[0];//只取第一个文件文件
          // let file=this.files[0];
          let fileReader=new FileReader();
          fileReader.onload=function (e) {//读取完毕时的回调
              img.src=e.target.result;
              img.style.display='block';
          }
          fileReader.readAsDataURL(file);//读取file文件对象
      })
  }
</script>
</html>

这种方式生成的资源地址是很长的


FileReader.png

URL.createObjectURL()

URL.createObjectURL()方法会创建一个 字符串,表示参数中给出的对象的URL。这个URL的生命周期和创建它的窗口中的 document绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。

这种方式使用不当会导致内存泄漏,在每次调用 createObjectURL()方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用URL.revokeObjectURL()方法来释放。浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
</head>
<body>
<input id="input" type="file">
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
    window.onload = function () {
        let input = document.getElementById('input');
        let img=document.getElementById('img');
        input.addEventListener('change', function (e) {
            //以下两种写法都能获取到file对象
            let file = this.files[0];//只取第一个文件文件
            // let file=e.target.files[0];
            let srcUrl=URL.createObjectURL(file);
            img.src=srcUrl;
            img.onload=function () {
                img.style.display='block';
                URL.revokeObjectURL(srcUrl);//释放内存
            }
        })
    }
</script>
</html>

这种方式生成的资源地址就很短


createObjectURL.png

添加文件的方式还有拖拽和粘贴

1.拖拽添加文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件拖拽</title>
</head>
<body>
<div id="file_area" style="position:absolute;width: 200px;height: 200px;background-color: #61b0d3">拖拽到此添加文件</div>
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
    window.onload = function () {
        let fileArea = document.getElementById('file_area');
        let img=document.getElementById('img');
        fileArea.addEventListener('dragenter', function (e) {
            e.stopPropagation();//阻止冒泡
            e.preventDefault();//阻止默认事件
        });
        fileArea.addEventListener('dragover', function (e) {
            e.stopPropagation();//阻止冒泡
            e.preventDefault();//阻止默认事件
        });
        fileArea.addEventListener('drop', function (e) {
            e.stopPropagation();//阻止冒泡
            e.preventDefault();//阻止默认事件
            let file = e.dataTransfer.files[0];//只取第一个文件测试
            //在页面上显示图片
            fileShowToUrl(file);
        });

        //文件转base64显示
        function fileShowToBase64(file) {
            let fileReader = new FileReader();
            fileReader.onload = function (e) {//读取完毕时的回调
                img.src = e.target.result;
                img.style.display='block';
            }
            fileReader.readAsDataURL(file);//读取file文件对象
        }

        //文件转url显示
        function fileShowToUrl(file) {
            let srcUrl = URL.createObjectURL(file);
            img.src = srcUrl;
            img.onload = function () {
                img.style.display='block';
                URL.revokeObjectURL(srcUrl);//释放内存
            }
        }
    }
</script>
</html>

将需要添加的文件拖拽到对应区域即可。


QQ录屏20220929095012 00_00_00-00_00_30.gif

2.粘贴文件

粘贴文件存在兼容性问题,不建议使用。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>粘贴文件显示</title>
</head>
<body>
<div id="clipboard" style="position: absolute;width: 300px;height: 300px;background-color: #bbffaa">粘贴板</div>
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
  window.onload=function () {
      let clipboard=document.getElementById('clipboard');
      let img=document.getElementById('img');
      clipboard.addEventListener('paste',function (e) {
          console.log('paste');
          if(!(e.clipboardData&&e.clipboardData.items)){
              return;
          }
          if(e.clipboardData.items[0]&&e.clipboardData.items[0].kind==='file'){//简单判断一下数据类型
              let file=e.clipboardData.files[0];//获取第一个文件
              fileShowToUrl(file);
          }
      })

      //文件转base64显示
      function fileShowToBase64(file) {
          let fileReader = new FileReader();
          fileReader.onload = function (e) {//读取完毕时的回调
              img.src = e.target.result;
              img.style.display='block';
          }
          fileReader.readAsDataURL(file);//读取file文件对象
      }

      //文件转url显示
      function fileShowToUrl(file) {
          let srcUrl = URL.createObjectURL(file);
          img.src = srcUrl;
          img.onload = function () {
              img.style.display='block';
              URL.revokeObjectURL(srcUrl);//释放内存
          }
      }
  }
</script>
</html>

复制文件后在粘贴区域按ctrl+v即可。


QQ录屏20220929095927 00_00_00-00_00_30.gif

参考文献:
https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
https://developer.mozilla.org/zh-CN/docs/Web/API/File

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容