# 6.1 基本使用

## 常用的有以下三個資料

* `FileList`：會是一個檔案列表物件，該物件裡面會有 File 物件。
* `File`：即 File 物件，通常代表的是某個檔案。
* `FileReader`：透過 FileReader 取得 File 物件的基本資訊。



## 練習 1：取得 FileList 物件與 File 物件

建立 `html5/file/file1.html` 檔案。

內容如下：建立一個 `type="file"` 的 `input` 標籤：

```markup
<!DOCTYPE html>
<html lang="zh-Hant">
  <head>
    <meta charset="utf-8">
    <title>File API</title>
  </head>
  <body>
    <input type="file" id="the_file">

  </body>
</html>
```

試著撰寫以下相關程式：

* `#the_file` 觸發 `change` 事件
* 取得檔案的物件( `this.files` )，然後於 console.log 中印出來。
* 取得第一個檔案( `this.files[0]` )，然後於 console.log 中印出來。



### 執行結果

執行結果如下圖，在 console 中觀察，的確有取得了 `FileList` 與 `File` 物件，如下圖：

![取得 FileList 與 File 物件](https://3693410308-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M06XOwutOnxz51nSIWs%2F-M1LJMbySiHWL1doUyjY%2F-M1LKrvXFbYzj_pdYHdP%2Ffilelist_file.png?alt=media\&token=a3476bc4-9afe-4bfc-8852-9ab682a66c04)

觸發 `change` 事件之後，就可以透過 `this.files` 和 `this.files[0]` 來取得 `FileList` 與 `File`。

* FileList：`FileList` 物件，存多個 `File` 物件。
* File：個別檔案的 `File` 物件，存著檔案的基本資料，從上圖可以看出主要有 `name`、`lastModified`、`size`、`type`。

{% hint style="info" %}
試著將 input 欄位，加上 **`multiple`** 屬性，變成多選，再觀察看看，使用者選了多個檔案的話，FileList 物件就會存多個 File。
{% endhint %}



參考作法：( [https://codepen.io/carlos411/pen/qBXGBMz](https://codepen.io/carlos411/pen/qBXGBMz) )

{% embed url="https://codepen.io/carlos411/pen/qBXGBMz" %}



## 關於 FileReader

常見用法：

```javascript
let reader = new FileReader(); // 用來讀取檔案的物件

reader.readAsDataURL(File); // 讀取檔案

// 檔案讀取完畢時觸發
reader.addEventListener("load", function () {
  
  // 可以透過 reader.result 取得圖片讀取完成時的 Base64 編碼格式
  
  // ... other code ...
});
```

關於 Base64 編碼：

{% hint style="info" %}
**Base64**可以用來將 binary 的位元組序列資料**編碼**成ASCII字元序列構成的文字。 使用時，在傳輸**編碼**方式中指定**Base64**。 使用的字元包括大小寫拉丁字母各26個、數字10個、加號 + 和斜槓 / ，共64個字元，等號 = 用來作為字尾用途。
{% endhint %}



## 練習 2：透過 FileReader 將圖片於網頁上預覽

一樣在 `file1.html` 網頁檔，繼續撰寫：(新增 CSS 及 ul 標籤)

```html
<!DOCTYPE html>
<html lang="zh-Hant">
  <head>
    <meta charset="utf-8">
    <title>File API</title>
    <style>
      img.preview{
        width: 200px;
      }
      ul{
        list-style: none;
        margin: 0;
        padding: 0;
      }
      ul > li{
        display: inline-block;
        vertical-align: top;
      }
    </style>
  </head>
  <body>
  
    <input type="file" id="the_file" multiple>
    <ul class="picture_list"></ul>

    <script>
      var the_file_element = document.getElementById("the_file");
      the_file_element.addEventListener("change", function(e){          
        // 寫在這
      });
    </script>
  </body>
</html>
```

試著寫出以下程式：

* 這個 `type="file"` 是可以選擇多個檔案，所以有加 `multiple` 屬性。
* 將所選的圖，呈現預覽圖在 `ul.picture_list` 標籤裡。
* 如果重選，要先將 ul 標籤裡的東西清空，再顯示預覽圖。



### 執行結果

選了檔案後的預覽結果，如下圖：

![](https://3693410308-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M06XOwutOnxz51nSIWs%2F-M1LvQ67uwsAOdGo-b_i%2F-M1LvdcP8DNOsHSGa5Uf%2Ffilereader_preview_width_border.png?alt=media\&token=31660d68-b65e-4e95-9a64-9762d12e4530)



{% hint style="info" %}
在 input 標籤上，可以加上 **`accept="image/*"`** 屬性，可限制使用者只能選擇圖檔相關。
{% endhint %}



參考作法( [https://codepen.io/carlos411/pen/BadgjEx](https://codepen.io/carlos411/pen/BadgjEx) )：

{% embed url="https://codepen.io/carlos411/pen/BadgjEx" %}



