プログラミング

[JavaScript] FileList オブジェクトを理解する

選択したファイルをあれこれ操作したい

下記のようなファイル選択画面でユーザが選択したファイルに関して、実際にサーバにアップロードする前にファイルの中身をチェックしたり、バリデーション(ファイル形式や容量制限)をかけたい…

ということって結構ありますよね。

なんの制限もなくドカドカ上げられちゃうとサーバが逼迫したりするので…

そういったときに役立つかもしれない? ファイル操作のアレコレや FileList オブジェクトに関してまとめてみようかな〜ということで今回は、

[JavaScript] FileList オブジェクトを理解する

と題して記事を書いていきたいと思います。

前回ブログはこちらから↓

FileList オブジェクトとは

input type=”file” 要素から得られる、ファイル情報が格納されたオブジェクト

ファイルを選択してアップロードする際などに使用する input type="file" でユーザがファイルを選択した後に返されるオブジェクトのことを FileList オブジェクト と言います。

<input type="file" id="file">

こういうやつですね↓デフォルトの見た目は言わずもがなダサい….

複数のファイルをアップロードできるようにする

複数のファイルを一気にアップロードしたい場合は、multiple 属性を追加します。

<input type="file" id="file" multiple>

FileList オブジェクトの中身を見てみよう

input type="file" の要素を取得して、change イベントを設定し、ユーザがファイルを選択した後に File オブジェクトの中身がどのようになっているか見てみましょう。

inputFile.files として、input 要素の files プロパティにアクセスすることで、選択したファイルの情報を取得することができます。FileList オブジェクトは配列ライクなオブジェクトを返します。ここでは先頭のファイル情報を取得したいわけなので、インデックス 0 ( = inputFile.files[0])を指定しています。

const inputFile = document.querySelector('#file'); // input type="file"の要素を取得
inputFile.addEventListener('change', () => {
  inputFile.files[0];
},false);

inputFile.files[0] の行でデバッグしてみると、 File オブジェクトの中身を確認することができます。

また、File オブジェクトのプロパティにアクセスすれば、それぞれの値を取得することができます。

console.log(inputFile.files[0].lastModified); // ファイルが最後に変更された日時(UNIXタイムスタンプ) →1614691281641
console.log(inputFile.files[0].lastModifiedDate); // ファイルが最後に変更された日時を表す Date オブジェクト(非推奨)
console.log(inputFile.files[0].name); // ファイル名 → test.jpg
console.log(inputFile.files[0].size); // ファイルサイズ(バイト) → 24778
console.log(inputFile.files[0].type); // ファイル形式 → image/jpeg

ファイルのバリデーション

ファイル数の制限

input 要素に multiple 属性が追加されている場合に、一度に選択できるファイル数を length プロパティを使って制限します。(下記では、3ファイルまでを上限としています)

const inputFileMulti = document.querySelector('#multi'); // input type="file"の要素を取得
inputFileMulti.addEventListener('change', () => {
  if(inputFileMulti.files.length > 3){
    alert('ファイルのアップロード制限数を超えています');
    inputFileMulti.value = '';
    return
  };
}, false);

inputFileMulti.value = ''; ( value プロパティに空文字を代入)とすることで、アップロードしたファイルをクリアします。こうすることで、alert メッセージを閉じた際にまた下記のような初期状態に戻ります。

ファイルサイズの制限

size プロパティを使って選択できるファイルの容量を制限できます。(下記では、1MBを上限としています)

const inputFile = document.querySelector('#file'); // input type="file"の要素を取得
inputFile.addEventListener('change', () => {
  const fileSizeLimit = 1024 * 1024; // 1MB
  if(inputFile.files[0].size > fileSizeLimit){
    alert('アップロード可能なファイル容量を超えています');
    inputFile.value = '';
    return;
  }
}, false);

1MBは 1,024×1,024=1,048,576バイト、なんですねぇ…(覚えてなかった)

ファイル形式の制限

type プロパティを使って選択できるファイルの形式を制限することができます。(下記では、選択できるファイルを JPEG か PNG としています)

const inputFile = document.querySelector('#file'); // input type="file"の要素を取得
inputFile.addEventListener('change', () => {
  if(
    inputFile.files[0].type !== 'image/jpeg' && 
    inputFile.files[0].type !== 'image/png'
  ){
    alert('選択できるファイル形式は jpeg か png となっています');
    inputFile.value = '';
    return;
  }
}, false);

FileList オブジェクトは配列( Array )ではなくオブジェクト

前述の通り files プロパティは戻り値として FileList オブジェクトが返すのですが、

この FileList オブジェクト、一見配列っぽいのですが、コイツは配列ではなく配列風オブジェクトなので、配列のメソッドが使えません….

なので、配列のメソッド使いたいな〜という時は Array.from() メソッドを使って配列に変換する必要があります。

const inputFileMulti = document.querySelector('#multi'); // input type="file"の要素を取得
inputFileMulti.addEventListener('change', () => {
  const inputFileArray = Array.from(inputFileMulti.files);  // オブジェクトを配列に変換
  console.log(Array.isArray(inputFileArray)); // → true
},false);

まとめ

今回は FileList オブジェクトの概要や、input type="file" で選択したファイルの中身を見たり、操作する方法についてまとめてみました。

ファイルのアップロードって、今回書いたバリデーションもそうだけど、そもそも input type="file" ダサい見た目もどうにかしないといけなかったり、やること多くて意外と大変なんだよなぁ…

って思ってます^^;

最近ジメジメしたり暑くなったり、天候変化が大きいので体調を崩しやすい時期かと思いますが、日々無理せず過ごしていきましょう…!

ここまでお読みいただき、ありがとうございました!