最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端图片预览

    正文概述 掘金(爱创课堂前端技术分享)   2020-12-08   301

    很多时候我们都会有图片上传的功能需求,如果我们先将图片上传到服务器,然后在将返回结果显示在前端,这样的操作性能开销太大,如果图片一多,简直要哭,而且万一还碰到了上传错误要删除的,那简直无法想象了。所以我们需要先将图片在前端展示后,然后由用户确认没有问题了,再统一上传,这样才是比较理想的。

    input

    type=file

    相信大家都知道,要在前端实现图片的上传,我们离不开的是一个 <input> type=file 的 input 元素,该元素可以允许用户选择一个或者多个文件。

        <input type="file">
    

    此时,我们点击 input 元素,就可以浏览本地文件并选择上传。但是,此时我们只能选择一个文件,而不能多个。这时就需要 <input> 标签的另一个属性 multiple

    multiple

    multipla 属性允许用户选择多个文件,他是一个不需要值的属性,也就是说,只要你的 input 标签上出现了这个属性,那么不论其值是什么,他都会支持多文件选择。通常来说我们使用 multiple 只会使用其属性名,而不会给他加值

        <input type='file' multiple>
    

    accept

    如果你尝试了以上标签及属性,你会发现你的不但能选择 image 文件,还能选择其他各种各样的文件。但是一般来说对我们有需要的只是 image 文件,至于其他什么的,爱咋咋地吧,只要不出来妨碍我就可以了。所以这时候我们需要 accept 的属性来进行限制。accept 属性接受逗号分隔的 MIME 类型字符串:

    1. accept='image/png' 或者 accept='.png' --只接受 .png 格式的图片
    2. accept='iamge/png,image/jpeg' 或者 accept='.png, .jpg .jpeg' 接受 .png .jpeg .jpg 格式的图片
    3. accept='image/*' 接受所有类型的 image 
    
    
        <input type='file' multiple accetp='image/*'>
    

    注: 'image/*' 在部分浏览器中(Chrome和Safari等Webkit浏览器)响应比较缓慢,可以用以下方法代替

        <<input type="file" multiple accept='image/png, image/jpeg, image/jpg, image/svg, image/gif'> 
    

    样式

    一般来说我们都会将 input 设置为 display:none, 然后通过 label 来设置其显示样式

        // 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>
    

    FileList 对象

    选中文件通过 HTMLInputElement.files 属性返回了一个 FileList 对象,这个对象是一个包含了许多 file 文件的列表。每个 file 对象包含了一下信息:

    1. name:文件名
    2. lastModified:文件最后一次修改时间(时间戳形式)
    3. lastModifiedDate:文件最后一次修改时间(UNIX timestamp形式)
    4. size: 文件大小(byte 为单位)
    5. type:文件 MIME 类型
    

    我们可以通过对 input 标签监听 change 事件:

        //  js
    
        document.getElementById('inputFile').addEventListener('change', changeHandler, false);
    
        function changeHandler(e) {
            var files = e.target.files;
            console.log(files) // 这里我们能获取到所选择的文件信息,需要注意的一点是 files 是个类数组对象。
        } 
    

    FileReader or 对象 URL

    当我们获取到文件对象信息 files 了以后,我们要如何将他在页面上预览出来,这里提供了两种方法:FileReader 或者 对象 URL。
    这两种方法该如何使用,又有何区别呢?

    1. FileReader

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

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

    2. load 事件:在文件加载成功后触发 load 事件

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

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

    usage:

        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!')
            }
        })
    

    2. 对象 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
            }
        }
    

    usage:

        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)
            }
        }
    
         
    
            } else {
                前端学习培训、视频教程、学习路线,添加威信  kaixin666haoyun  与我联系
            }
    

    起源地下载网 » 前端图片预览

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元