上傳圖片實時預覽

引入

當使用<input type=file>上傳圖片文件時,如何在上傳到服務器以前,在本地進行預覽?html

FileReader 對象

FileReader對象容許Web應用程序異步讀取用戶計算機上的文件。使用new建立一個FileReader實例對象:前端

let fileReader = new FileReader();

屬性

  • error:在讀取時發生的錯誤
  • readyState:fileReader當前狀態
  • result:讀取到的文件內容,只有在讀取操做完成後有效

方法

  • abort():終止讀取操做
  • readAsDateURL():讀取文件中的內容,讀取完成後調用onloadend方法,結果result中包含一個data:URL格式的字符串表示文件內容(針對圖片就是base64格式的字符串)

事件處理程序

  • onabort:讀取被終止時被調用
  • onerror:讀取錯誤時調用
  • onload:讀取成功時調用
  • onloadend:讀取完成時調用,不管成功失敗, 在onloadonerror後調用
  • onloadstart:讀取開始前調用
  • onprogress:讀取過程當中週期調用、

兼容性

image

使用FileReader對象預覽圖片

  • <input>onchange事件中獲取上傳的圖片對象
  • 使用<input>event.target.files獲取上傳對象的類數組對象,每一項的name屬性對應文件名
  • <input>中增長multiple屬性,上傳多個文件
  • 建立FileReader對象,並經過readAsDateURL()方法,傳入要預覽的文件對象,在onload回調函數中對FileReader對象的result進行處理

代碼:

預覽多張圖片chrome

<body>
<label><input type="file" id="file" multiple></label>
<div id="preview" class="preview">
  <img id="img" src="default.png">
</div>
</body>
<script>
  'use strict';
  let input = document.querySelector('#file'),
    wrapper = document.querySelector('#preview'),
    img = document.querySelector('#img');

  function preview(files) {
    Object.keys(files).forEach(function (file) {
      let fileReader = new FileReader();
      fileReader.readAsDataURL(files[file]);
      fileReader.onload = function () {
        img.src = fileReader.result;
        img.title = files[file].name;
      };
    })
  }

  input.onchange = function (e) {
    let files = e.target.files;
    preview(files)
  };
</script>

拖拽預覽

不經過點擊事件而是經過將圖片拖拽到指定區域實現預覽。segmentfault

在拖放過程當中會觸發的事件:數組

  • 在源元素上觸發的事件(須要設置 draggable 屬性)瀏覽器

    • ondragstart:開始拖動時觸發
    • ondrag:拖動時觸發
    • ondragend:拖動完成時觸發
  • 釋放時觸發的事件安全

    • ondragenter:進入容器範圍時觸發
    • ondragover:拖動時觸發(觸發間隔350毫秒)
    • ondragleave:離開容器範圍時觸發
    • ondrop:拖動過程當中,釋放鼠標按鍵時觸發

顯然這裏須要使用的是 ondrop 事件,可是須要注意,使用ondrop 事件須要阻止瀏覽器默認行爲,不然不會觸發服務器

document.addEventListener("drop", function(e) { //釋放
  e.preventDefault();
});
document.addEventListener("dragenter", function(e) { //拖進
  e.preventDefault();
});
document.addEventListener("dragleave", function(e) { //拖離
  e.preventDefault();
});
document.addEventListener("dragover", function(e) { //拖來拖去
  e.preventDefault();
});

而後在 ondrop 事件中觸發上面的函數就能夠實現圖片預覽了。注意,`inputonchange 事件獲取文件對象是 e.target.files,而 drop 事件則是 e.dataTransfer.filesapp

window.URL.createObjectURL()

也能夠經過這個方法來實現圖片的預覽異步

URL.createObjectURL() 靜態方法會建立一個 DOMString,這個新的URL 對象表示指定的 File 對象或 Blob 對象。

在每次調用 createObjectURL() 方法時,都會建立一個新的 URL 對象,即便你已經用相同的對象做爲參數建立過。當再也不須要這些 URL 對象時,每一個對象必須經過調用 URL.revokeObjectURL() 方法來釋放。瀏覽器會在文檔退出的時候自動釋放它們,可是爲了得到最佳性能和內存使用情況,你應該在安全的時機主動釋放掉它們。
// 使用 createObjectURL
function preview2(files) {
  Object.keys(files).forEach(function(file) {
    img.src = window.URL.createObjectURL(files[file]);
  })
}

區別

因爲 URL.createObjectURL() 是瀏覽器自身的接口,貌似性能會更好一點

而且可能比fileReader對IE的兼容性好一些,問題少一些?

不過能夠兩者選擇使用吧,多一個選擇不是壞事

參考

相關文章
相關標籤/搜索