走進HTML5-實現網站中常見的拖拽上傳文件

歡迎關注個人我的博客分享一些前端技術、面試題、面試技巧等前端

當咱們學習了 HTML 提供的原生拖放(drag & drop)後,是時候想想這個東西能夠用來做什麼能夠在何時使用使用的場景等等git

場景分析

當咱們在註冊成功一個帳戶時,通常網站會讓咱們上傳咱們的用戶頭像,或者在實名認證的時候會涉及到身份證圖片上傳到等,這時候咱們可使用input提供的file屬性進行選擇本地文件進行上傳。github

實名認證

咱們再想一下,當在電腦端的狀況下,當用戶打開文件選擇框時再尋找圖片對應的文件夾,再進行選取文件的時候是否是會有點麻煩呢?咱們可不可讓用戶找到圖片文件,直接引入實現上傳呢?答案是能夠的。web

怎麼作

通過這些分析後,咱們能夠嘗試使用 HTML5 提供的拖拽,使得目標元素增長讀取文件功能,而後使用 ajax 實現圖片上傳。面試

談一談咱們須要使用到的技術:ajax

  • Drag & Drop: HTML5 基於拖拽的事件機制
  • File API: 能夠很方便的讓 Web 應用訪問文件對象,File API 包括 FileList、Blob、File、FileReader、URI scheme,本文主要講解拖拽上傳中用到的 FileList 和 FileReader 接口。
  • FormData: FormData 是基於 XMLHttpRequest Level 2 的新接口,能夠方便 web 應用模擬 Form 表單數據,最重要的是它支持文件的二進制流數據,這樣咱們就可以經過它來實現 AJAX 向後端發送文件數據了。

HTML5 拖拽事件

關於 Drag & Drop 拖拽事件,以前我寫過一篇專門介紹的文章,HTML5-拖拽,你們有興趣的話能夠點擊連接查看,我在這裏就不在多囉嗦了~下面直接出拖拽上傳的簡要代碼示例後端

var oDragWrap = document.body;

//拖進
oDragWrap.addEventListener(
  "dragenter",
  function(e) {
    e.preventDefault();
  },
  false
);

//拖離
oDragWrap.addEventListener(
  "dragleave",
  function(e) {
    dragleaveHandler(e);
  },
  false
);

//拖來拖去 , 必定要注意dragover事件必定要清除默認事件
//否則會沒法觸發後面的drop事件
oDragWrap.addEventListener(
  "dragover",
  function(e) {
    e.preventDefault();
  },
  false
);

//扔
oDragWrap.addEventListener(
  "drop",
  function(e) {
    dropHandler(e);
  },
  false
);

var dropHandler = function(e) {
  //將本地圖片拖拽到頁面中後要進行的處理都在這
};
複製代碼

獲取文件數據 HTML5 File API

File API 中的 FileReader 接口,做爲 File API 的一部分,FileReader 專門用來讀取文件。咱們在這裏主要介紹一些 File API 中的 FileList 接口,它主要經過兩個途徑獲取本地文件列表,一是<input type="file"/>的表單形式,另外一種則是e.dataTransfer.files拖拽事件傳遞的文件信息。數組

var fileList = e.dataTransfer.files;
複製代碼

使用 files 方法將會獲取到拖拽文件的數組形式的數據,每一個文件佔用一個數組的索引,若是索引不存在文件數據,將返回 Null。能夠經過length屬性獲取文件的數量。服務器

var fileNum = fileList.length;
複製代碼

拖拽上傳須要注意的是須要判斷兩個條件app

  1. 拖拽的是文件而不是頁面的元素
  2. 拖拽的是圖片而不是其餘類型的文件,能夠經過 file.type 屬性獲取文件的類型
// 檢測是不是拖拽文件到頁面的操做
if (fileList.length === 0) {
  return;
}

// 檢測文件是否是圖片
if (fileList[0].type.indexOf("image") === -1) {
  return;
}
複製代碼

下面咱們看看結合以前的拖拽事件,來實現拖拽圖片並在頁面中預覽

var dropHandler = function(e) {
  e.preventDefault(); //獲取文件列表

  var fileList = e.dataTransfer.files;

  //檢測是不是拖拽文件到頁面的操做
  if (fileList.length == 0) {
    return;
  }

  //檢測文件是否是圖片
  if (fileList[0].type.indexOf("image") === -1) {
    return;
  }

  //實例化file reader對象
  var reader = new FileReader();
  var img = document.createElement("img");

  reader.onload = function(e) {
    img.src = this.result;
    oDragWrap.appendChild(img);
  };
  reader.readAsDataURL(fileList[0]);
};
複製代碼

n34B6S.gif

當完成以上操做後,相信你能夠成功的完成了拖拽圖片預覽的操做。當你查看 img 標籤時會發現,img的src屬性是一個超長的文件二進制數據,當你須要不少這種的img元素時,建議將展現區域脫離文檔流,讓其絕對定位減小頁面的 reflow

AJAX 上傳圖片

既然已經獲取到拖拽到web頁面中的圖片數據了,下一步就是將其發送到服務器端。

總結

  1. 監聽拖拽: 監聽頁面元素的拖拽事件,包括: dragenterdragoverdragleavedrop,必定要將dragover的默認事件取消掉,否則沒法觸發drop事件。如需拖拽頁面裏面的元素,須要給其添加屬性draggable="true"
  2. 獲取拖拽文件: 在 drop 事件觸發後經過e.dataTransfer.files獲取拖拽文件列表,必定要將drop的默認事件取消掉,不然會默認打開文件length屬性獲取文件數量,type屬性獲取文件類型
  3. 讀取圖片數據並添加預覽圖: 實例化FileReader對象,經過其readAsDataURL(file)方法獲取文件二進制流,並監聽其onload事件,將e.result賦值給img的src屬性,最後將圖片添加到DOM中
  4. 發送圖片數據

但願對讀完本文的你有幫助、有啓發,若是有不足之處,歡迎批評指正交流!

歡迎關注個人我的博客分享一些前端技術、面試題、面試技巧等

辛苦整理良久,還望手動點贊鼓勵~


'摘抄'不是單純的「粘貼->複製」,而是眼到,手到,心到的一字一句敲打下來。

博客聲明:全部轉載的文章、圖片僅用於做者本人收藏學習目的,被要求或認爲適當時,將標註署名與來源。若不肯某一做品被轉用,請及時通知本站,本站將予以及時刪除。

相關文章
相關標籤/搜索