前端上传文件预览,FileReader or 对象 URL

1.FileReader

FileReader 实现了一种异步的读取机制。他必须先通过 FileReader() 构造函数创建出一个 fileReader 实例。该实例实现了一下几个方法和事件(部分):

readerAsDataURL(file): 读取文件并以数据 URI 形式保存在 result 属性中

load 事件:在文件加载成功后触发 lo## 标题ad 事件

error 事件:在文件加载失败后触发 error 事件

progress 事件:在读取文件的过程中触发 progress 事件,该事件可以近似(间隔性触发,不是实时响应)监听文件上传进度。该方法有三个属性:lengthComputable(进度信息是否可用), loaded(已经加载了多少), total总共有多少。

    files.forEach(function(item) {
        var reader = new FileReader();
        reader.readAsDataURL(item);
        reader.onprogress = function(e) {
            if (e.lengthComputable) {
                // 简单把进度信息打印到控制台吧
                console.log(e.loaded / e.total + '%') 
            }
        }
        reader.onload = function(e) {
            var image = new Image()
            image.src = e.target.result
            body.appendChild(image)
        }
        reader.onerror = function(e) {
            console.log('there is an error!')
        }
    })

对象 URL

对象 URL 指的是引用保存在 File 或 Blob 中的数据 URL。使用对象 URL 的时候不用像 FIleReader 一样要先把数据读取到 JavaScript 中,他可以引用 内存中 URL 地址而使用。

创建对象 URL 方法: window.URL.createObjectURL()。兼容写法:

 function creatObjectURL(file) {
        if (window.URL) {
            return window.URL.createObjectURL(file);
        } else if (window.webkitURL) {
            return window.webkitURL.createObjectURL(file);
        } else {
            return null
        }
    }
files.forEach(function(item) {
        var url = createObjectURL(item)
        var image = new Image()
        image.src = url
        body.appendChild(image)
    })

区别

  1. FileReader 是异步操作,而对象 URL 是同步操作

  2. FileReader.readAsDataURL 返回的是一个包含更多字节的 base64 格式,createObejctURL 返回的是一个带 hash 的 URL。

  3. 由于两者返回形式不同,FileReader.readerAsDataURL 会占用更多内存,但是当你不再使用他的时候,他会自动释放内存,而 createObjectURL 则只有当你的页面关闭或者手动调用 revokeObejctURL 的时候才能释放内存。

  4. 从兼容性来说: createObjectURL 和 FileReader.readerAsDataURL 都兼容 IE10+ 和现代所有主流浏览器

  5. createObjectURL 相对 FileReader.readerAsDataURL,效率较高。但是如果图片较多,则最好手动清除内存,可以把 URL 当做参数直接传给 window.URL.revokeObjectURL()。兼容写法:

 function revokeObjectURL(url) {
     if (widnow.URL) {
         return window.URL.revokeObjectURL(url)
     } else {
         return window.webkitURL.revokeObjectURL(url)
     }
 }

简单实现

   // css

    input{
        display:none;
    }
    label{
        // 关于label样式
    }

    // html

    <input type='file' multiple accept='image/png, image/jpeg, image/jpg, image/svg, image/gif' id='inputFile'>
    <label for="inputFile">上传图片</label>

    // js 

    var inputFile = document.getElementById('inputFile')
    var body = document.body || document.getElementsByTagName('body')[0]

    inputFile.addEventListener('change', changeHandler, false)

    function changeHandler(e) {
        var files = Array.from(e.target.files)
        files.forEach(function(item) {
            var image = new Image()
            image.src = createObjectURL(item)
            body.appendChild(image)
            image.onload = function() {
                revokeObjectURL(this.src)
            }
        })
    }

    function createObjectURL(file) {
        if (window.URL) {
            return window.URL.createObjectURL(file)
        } else {
            return window.webkitURL.createObjectURL(file)
        }
    }

    function revokeObjectURL(file) {
        if (window.URL) {
            return window.URL.revokeObjectURL(file)
        } else {
            return window.webkitURL.revokeObjectURL(file)
        }
    }

拓展:URI与URL的区别

  1. URL(统一资源定位符)主要用于链接网页,网页组件或网页上的程序,借助访问方法(http,ftp,mailto等协议)来检索位置资源。相反,URI(统一资源标识符)用于定义项目的标识,此处单词标识符表示将一个资源与其他资源区分开,而不管使用的方法(URL或URN)
  2. URL是URI,但URI永远不能是URL
  3. URL指定要使用的协议类型,而URI不涉及协议规范
    在这里插入图片描述

参考链接:https://juejin.cn/post/6903691429030133768
(ps. oschina上面也有很多好文章)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值