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;
      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,不嚴謹的地方和丑陋的樣式就多多包涵了。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM