• input[type='file']样式美化及实现图片预览


    前言

      上传图片是常见的需求,多使用input标签。本文主要介绍 input标签的样式美化 和 实现图片预览

      用到的知识点有:

        1、input标签的使用

        2、filelist对象 和 file对象

        3、fileReader对象

    样式美化

      原生的input标签样式单一,且在不同浏览器下的表现还不一致。所以为了美观和统一,我们需要自定义input标签的样式。

      实现的方式有很多中,这里采用的是:用一个div将input标签包裹,然后再将input标签透明度设置为0,再对div设置自己需要的样式。html和css如下:

          <div class="upload-file">
            <input type="file" class="input-file" multiple="true">  // mulitiple属性控制是否允许上传多个文件
            <span class="tip">点击上传图片</span>
          </div>
        .upload-file{
          position: relative;
          width: 100px;
          padding: 10px 15px;
          border: 1px solid rgb(119, 154, 80);
          border-radius: 5px;
          background-color: rgb(66, 215, 142);
          color: #333333;
          font-size: 14px;
          text-align: center;
          overflow: hidden;
        }
    
        .upload-file span{ //单行显示
          text-overflow: ellipsis;
          white-space: nowrap;
          overflow: hidden;
        }
    
        .upload-file:hover{ //简单的hover效果
          font-size: 15px;
          border-color: rgb(39, 226, 81);
        }
    
        .upload-file input[type='file']{
          height: 100%;
          width: 100%;
          position: absolute; //设置为绝对定位,不会影响到其他元素
          top: 0;
          right: 0;
          opacity: 0;   //透明度为0
          filter: alpha(opacity=0);
          cursor: pointer;
        }
    View Code

      这样点击div,其实也就点击到了input标签,可已正常触发选择文件的。

      效果如下:

                   

       

      但是这样就会产生一个问题,如何获取选择文件的文件名称呢?需要用到file对象的name属性

    filelist和file对象--获取文件名

      input元素选择文件后会返回FileList对象,比如

    //input元素
    var fileInput = document.querySelector('.input-file');
    //filelist对象
    var filelist = fileInput.files
    //file对象 

    var file = filelist.item(0)
    或者 var file = filelist[0]

      我们知道,每个input[type='file']都有一个files属性,返回的就是filelist 就和nodelist类似,不是数组。filelist就是由多个file对象组成的,每个file对象都是一个文件。

      filelist对象有个length属性,可以获取长度;还有item(index)方法,可以获取到file对象,当然可以通过 filelist[index]来获取。

      file对象常用的属性有:

        lastModified : 返回当前 File 对象所引用文件最后修改时间, 自 1970年1月1日0:00 以来的毫秒数。
        lastModifiedDate : 返回当前 File 对象所引用文件最后修改时间的 Date 对象。
        name : 文件名。
        size : 文件大小。
        type :文件类型。

      所以我们可以通过file对象的name属性来获取到文件名,在修改到span元素中

        var fileInput = document.querySelector('.input-file');
        var tip = document.querySelector('.tip');
     
        fileInput.addEventListener('change',function(e){ //监听change事件,选择文件后触发
          if(this.files.length === 1){ //处理文件名
            tip.textContent = this.files[0].name;
          }else {
            tip.textContent = '已选择 ' + this.files.length + ' 个文件';
          }
        })

      效果如下:

          

      现在已经自定义了input[type='file']的样式,而且实现了原有的功能。那么如何实现图片预览呢?

    FileReader 对象 --实现图片预览

       FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容。也就是说FIlereader对象可以读取到input选择的文件。filereader对象在读取file对象时,当读取完成时,readystate属性的值会变为DONE,会触发load事件。而且有多种读取方式:

      readAsBinaryString()读取完成后,result属性中包含原始数据的二进制数据,readAsDataURL()读取完成后,result属性中包含data:url格式的数据,readAsText()读取完成后,result属性中包含字符串格式的数据,readAsArrayBuffer()result属性中将包含一个ArrayBuffer对象以表示所读取文件的内容。

      这里上传的时图片,所以使用readAsDataURL()读取。现在html中加入个预览触发按钮,而预览图片存放的区域。

    //简单结构 
         <div class="preview">
            <button type="button" name="button">预览</button>
          </div>
    
    //样式
        .preview{
          margin-top: 10px;
           150px;
        }
    
        .preview img{
          margin: 5px 0;
           100%;
        }

      实现预览功能,注释中已有详细解释,不再重复。注意一定要等filereader读取完成后,再进行赋值,不然图片的src属性会是空的

       
        var preview = document.querySelector('.preview')
        var previewBtn = preview.children[0];
    
        previewBtn.addEventListener('click',function(e){
          var filelist = fileInput.files;
          if(filelist.length < 1){
            alert("未选择图片,无法预览");
            return false;
          }
    
          [].slice.call(filelist).forEach(function(value,index){  //遍历file对象
            var fileReader = new FileReader(); //创建一个filereader对象
            var img = new Image();  //创建一个图片对象
            fileReader.readAsDataURL(value)  //读取所上传对的文件
            fileReader.onload = function(){
              img.src = this.result;   //读取完成后,赋值给img对象
              preview.appendChild(img)  //添加到预览区域
            }
          })
        })

      效果如下:

      

    总结

      总结来说,就是  input[type='file']的files属性 --> filelist对象 --> file对象 --> filereader对象读取file对象。通过它们的一些参数值实现我们想要的功能。由于只是简单demo,不严谨的地方和丑陋的样式就多多包涵了。

      再下一步就是要上传图片到服务器了,会在下个随笔中记录。

  • 相关阅读:
    Codeforces 525C Om Nom and Candies 枚举 + 复杂度分析
    Codeforces 526B Om Nom and Dark Park 树形dp
    Codeforces 526A King of Thieves 枚举
    Regionals 2014 Asia
    Regionals 2014 Asia
    access数据库和sqlsever数据库sql语句的布尔值boolean的写法
    取消阴影行
    引用其他单元的2种方法
    选中阴影行
    全选
  • 原文地址:https://www.cnblogs.com/shapeY/p/7891636.html
Copyright © 2020-2023  润新知