国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

「HTML5」FileAPI 文件操作實戰

Jacendfeng / 1552人閱讀

摘要:準備工作首先,我們的來自于標簽中選中的文件列表。用戶選中的文件信息也會傳入回調函數的第一個參數中。唯一需要特殊處理的是文件對象的獲取入口改變了。對于標簽,監聽事件,存放在中對于拖拽操作,存放在拖拽事件的回調函數參數里,通過訪問即可。

本文來自《FileAPI 文件操作實戰》

其他所有系列都放在了Github。歡迎交流和Star

介紹

HTML5 為我們提供了 File API 相關規范。主要涉及 File 接口 和 FileReader 對象 。

本文整理了兼容性檢測、文件選擇、屬性讀取、文件讀取、進度監控、大文件分片上傳以及拖拽上傳等開發中常見的前端文件操作。

準備工作

首先,我們的 File 來自于標簽中選中的文件列表。所以,準備如下的 HTML 代碼:


檢測兼容性

File 對象是特殊類型的 Blob。在 script 入口處,應該檢測當前瀏覽器是否支持 File API:

if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
  throw new Error("當前瀏覽器對FileAPI的支持不完善");
}
監聽文件選擇

對于 type 為 file 類型的標簽,在選擇文件的時候,會觸發change事件。用戶選中的文件信息也會傳入回調函數的第一個參數中。

function handleFileSelect(event) {
  const { files } = event.target;
  if (!files.length) {
    console.log("沒有選擇文件");
    return;
  }

  console.log("選中的文件信息是:", files);
}

document
  .querySelector("#files")
  .addEventListener("change", handleFileSelect, false);
文件屬性-File

event.target.files 是一個FileList對象,它是一個由File對象組成的列表。

每個 File 對象,保存著選中的對應文件的屬性。常用的用:

name:文件名

type:文件類型

size:文件大小

下面,通過 type 屬性,過濾掉非圖片類型的文件,只展示圖片類型文件的信息:

function handleFileSelect(event) {
  const { files } = event.target;
  if (!files.length) {
    console.log("沒有選擇文件");
    return;
  }

  const innerHTML = [];
  const reImage = /image.*/;

  for (let file of files) {
    if (!reImage.test(file.type)) {
      continue;
    }

    innerHTML.push(
      `
      
  • ${file.name} (${file.type || "n/a"}) - ${file.size} bytes
  • ` ); } document.querySelector("#list").innerHTML = `
      ${innerHTML.join("")}
    `; }
    讀取文件-FileReader

    還是以圖片讀取為例,讀取并且顯示所有的圖片類型文件。

    文件讀取需要使用FileReader對象,它常用 3 個回調方法:

    onload: 文件讀取完成

    onloadstart:文件上傳開始

    onprogress : 文件上傳中觸發

    Image類似,在讀取文件之前,需要先綁定事件處理。它讀取操作有:readAsArrayBuffer、readAsDataURL、readAsBinaryString、readAsText。傳入的參數就是File對象。

    那么這幾個方法有什么區別呢?不同的讀取方式,回調事件onload接受到的event.target.result不相同。比如,readAsDataURL讀取的話,result 是一個圖片的 url。

    下面就是讀取圖片文件,然后展示的一個例子:

    function handleFileSelect(event) {
      let { files } = event.target;
      if (!files.length) {
        return;
      }
    
      let vm = document.createDocumentFragment(),
        re = /image.*/,
        loaded = 0, // 完成加載的圖片數量
        total = 0; // 總共圖片數量
    
      // 統計image文件數量
      for (let file of files) {
        re.test(file.type) && total++;
      }
    
      // onloadstart回調
      const handleLoadStart = (ev, file) =>
        console.log(`>>> Start load ${file.name}`);
      // onload回調
      const handleOnload = (ev, file) => {
        console.log(`<<< End load ${file.name}`);
    
        const img = document.createElement("img");
        img.height = 250;
        img.width = 250;
        img.src = ev.target.result;
        vm.appendChild(img);
    
        // 完成加載后,將其放入dom元素中
        if (++loaded === total) {
          document.querySelector("#images").appendChild(vm);
        }
      };
    
      for (let file of files) {
        if (!re.test(file.type)) {
          continue;
        }
    
        const reader = new FileReader();
        reader.onloadstart = ev => handleLoadStart(ev, file);
        reader.onload = ev => handleOnload(ev, file);
        // 讀取文件對象
        reader.readAsDataURL(file);
      }
    }
    
    document
      .querySelector("#files")
      .addEventListener("change", handleFileSelect, false);
    監控讀取進度

    在監控讀取進度的時候,主要是處理 FileReader 對象上的 onprogress 事件。

    下面的例子,請打開一個較大的文件來查看效果(否則一下就讀取完了):

    function handleFileSelect(event) {
      let { files } = event.target;
      if (!files.length) {
        return;
      }
    
      const handleLoadStart = (ev, file) =>
        console.log(`>>> Start load ${file.name}`);
      const handleProgress = (ev, file) => {
        if (!ev.lengthComputable) {
          return;
        }
        // 計算進度,并且以百分比形式展示
        const percent = Math.round((ev.loaded / ev.total) * 100);
        console.log(`<<< Loding ${file.name}, progress is ${percent}%`);
      };
    
      for (let file of files) {
        const reader = new FileReader();
        reader.onloadstart = ev => handleLoadStart(ev, file);
        reader.onprogress = ev => handleProgress(ev, file);
        reader.readAsArrayBuffer(file);
      }
    }
    
    document
      .querySelector("#files")
      .addEventListener("change", handleFileSelect, false);
    大文件分片讀取

    在對于超大文件,一般采用分片上傳的思路解決。文章開頭有講到,File 是 Blob 的一個特例。而 Blob 上有一個slice 方法,通過它,前端就可以實現分片讀取大文件的操作。

    為了方便說明,請先準備好一個 txt 文件,文件內容就是:hello world

    示例代碼如下,代碼中只讀取前 5 個字節,由于每個英文字母占 1 個字節,所以打印結果應該是“hello”。

    function handleFileSelect(event) {
      let { files } = event.target;
      if (!files.length) {
        return;
      }
      // 為了方便說明,這里僅僅讀取第一個文件
      const file = files[0];
      // 讀取前5個字節的內容
      const blob = file.slice(0, 5);
    
      const reader = new FileReader();
      // 控制臺輸出結果應該是:hello
      reader.onload = ev => console.log(ev.target.result);
      reader.readAsText(blob);
    }
    
    document
      .querySelector("#files")
      .addEventListener("change", handleFileSelect, false);
    拖拽上傳

    和前面所述的 File API 相關是完全一樣的。唯一需要特殊處理的是文件對象的獲取入口改變了。對于標簽,監聽 onchange 事件,FileList 存放在 event.target.files 中;對于拖拽操作,FileList 存放在拖拽事件的回調函數參數里,通過 event.dataTransfer.files 訪問即可。

    需要修改一下 html 代碼:

    
    
      
      
    
    
      

    腳本文件的代碼如下:

    function handleDropover(event) {
      event.stopPropagation();
      event.preventDefault();
    }
    
    function handleDrop(event) {
      event.stopPropagation();
      event.preventDefault();
      /***** 訪問拖拽文件 *****/
      const files = event.dataTransfer.files;
      console.log(files);
      /**********/
    }
    
    const target = document.querySelector("#container");
    target.addEventListener("dragover", handleDropover);
    target.addEventListener("drop", handleDrop);
    后端相關

    后端相關超出了本文的討論范圍,可以參考這篇文章。

    文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

    轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105889.html

    相關文章

    • 瀏覽器端下載那些事

      摘要:三瀏覽器方式相信大家對這個對象也不太陌生,它是標準里的一個二進制數據對象,可以與對象配合,進行文件的下載。其實這樣一個簡單的,就可以實現瀏覽器端自己的下載了。 一、背景 最近寫了一個react的組件,用來做文件導出。環境是ie10+。細一點說,就是 1、讀取form里的數據 2、向服務端發請求,并下載文件;要求拿到請求狀態,如果出錯及時反饋給用戶。 第一個需求,我們借用了jquer...

      3fuyu 評論0 收藏0
    • [練習]JS鼠標拖拽(DnD)操作

      拖放(Drag and Drop,DnD)操作因為涉及到與底層OS的結合,所以是較為復雜的交互操作。 這里先實現一個簡單的拖拽圖片到瀏覽器顯示到操作, 主要用到了HTML5中的FileAPI: 先上DEMODnD demo 需要注意的是瀏覽器通過取消相應的拖拽事件來表明它對該事件有興趣, 比如通過取消dragover來表明瀏覽器已經做好準備接受進一步的拖拽,接著說dragend最后到drop,dr...

      jsummer 評論0 收藏0
    • Vue2.0利用vue-resource上傳文件到七牛

      摘要:年底,公司項目番茄表單的前端部分,開始了從傳統的到的徹底重構。上傳流程圖不重要看文字事件觸發后,先去如果是圖片,可以同時通過以及將圖片預覽在頁面上后臺請求七牛的上傳,將拿到的和以及通過傳遞過來的一起到中。 關于上傳,總是有很多可以說道的。16年底,公司項目番茄表單的前端部分,開始了從傳統的jquery到vue 2.0的徹底重構。但是上傳部分,無論是之前的傳統版本,還是Vue新版本,都是...

      lcodecorex 評論0 收藏0

    發表評論

    0條評論

    最新活動
    閱讀需要支付1元查看
    <