input[type='file']樣式美化及實現圖片預覽

前言

  上傳圖片是常見的需求,多使用input標籤。本文主要介紹 input標籤的樣式美化 和 實現圖片預覽css

  用到的知識點有:html

    一、input標籤的使用node

    二、filelist對象 和 file對象數組

    三、fileReader對象瀏覽器

樣式美化

  原生的input標籤樣式單一,且在不一樣瀏覽器下的表現還不一致。因此爲了美觀和統一,咱們須要自定義input標籤的樣式。服務器

  實現的方式有不少中,這裏採用的是:用一個div將input標籤包裹,而後再將input標籤透明度設置爲0,再對div設置本身須要的樣式。html和css以下:app

      <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標籤,可已正常觸發選擇文件的。異步

  效果以下:ide

               

   

  可是這樣就會產生一個問題,如何獲取選擇文件的文件名稱呢?須要用到file對象的name屬性this

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;
      width: 150px;
    }

    .preview img{
      margin: 5px 0;
      width: 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,不嚴謹的地方和醜陋的樣式就多多包涵了。

  再下一步就是要上傳圖片到服務器了,會在下個隨筆中記錄。

相關文章
相關標籤/搜索