- input type=”file” は「ユーザーにファイルを選んでもらうための唯一の正規ルート」
- 基本の形:input type=”file” と change イベント
- accept 属性で「選んでほしいファイルの種類」をヒントに出す
- multiple 属性で「複数ファイル」を選べるようにする
- 例題①:選んだ画像ファイルをプレビュー表示する
- 例題②:選んだテキストファイルの中身を画面に表示する
- 重要ポイント:セキュリティと制約をちゃんと理解する
- 重要ポイント:UI としての input type=”file” をどう扱うか
- 例題③:input type=”file” とドラッグ&ドロップを両方サポートする
- 初心者として input type=”file” で本当に掴んでほしいこと
input type=”file” は「ユーザーにファイルを選んでもらうための唯一の正規ルート」
まず大前提として、
ブラウザの JavaScript は、勝手にユーザーのパソコンの中を覗けません。
「このファイルをブラウザに渡してもいいよ」と
ユーザーが自分の手で選んだときだけ、そのファイルに触れます。
その“入口”になるのが <input type="file"> です。
この要素があるからこそ、
- 画像をアップロード
- CSV を読み込んで処理
- PDF をサーバーに送信
- ローカルのテキストを読み込んで表示
といったことが、安全に実現できます。
基本の形:input type=”file” と change イベント
HTML と JavaScript の最小構成
HTML:
<input type="file" id="fileInput">
JavaScript:
const input = document.querySelector("#fileInput");
input.addEventListener("change", () => {
const files = input.files; // FileList
console.log(files);
});
JavaScriptここで重要なのは 2 つです。
1つ目は、change イベントが「ユーザーがファイル選択ダイアログで決定したタイミング」で発火すること。
2つ目は、input.files に FileList(ファイルの配列のようなもの) が入ること。
FileList の中身は File オブジェクトです。
const file = input.files[0];
console.log(file.name); // ファイル名
console.log(file.size); // バイト数
console.log(file.type); // MIME タイプ(image/png など)
JavaScriptここまでが「ファイルを選んでもらう」部分。
この先は File API / FileReader / Blob の世界につながっていきます。
accept 属性で「選んでほしいファイルの種類」をヒントに出す
画像だけ選ばせたい場合
HTML:
<input type="file" id="imageInput" accept="image/*">
accept="image/*" と書くと、
ファイル選択ダイアログで「画像ファイル」が優先的に表示されます。
他にも、
<input type="file" accept=".txt">
<input type="file" accept=".csv,.tsv">
<input type="file" accept="application/pdf">
のように、拡張子や MIME タイプで指定できます。
ここでのポイントは、
- accept は「ユーザーへのヒント」であって、完全な制限ではない
- JavaScript 側でも
file.typeやfile.nameをチェックしておくと安心
ということです。
例えば、画像だけ受け付けたいなら、
こういうチェックを入れます。
const file = input.files[0];
if (!file.type.startsWith("image/")) {
alert("画像ファイルを選んでください");
return;
}
JavaScriptmultiple 属性で「複数ファイル」を選べるようにする
HTML 側で multiple を付ける
<input type="file" id="multiInput" multiple>
これで、ユーザーは一度に複数のファイルを選べます。
JavaScript 側では、input.files に複数の File が入ります。
const input = document.querySelector("#multiInput");
input.addEventListener("change", () => {
const files = input.files;
Array.from(files).forEach((file) => {
console.log(file.name, file.size);
});
});
JavaScriptここで押さえておきたいのは、
filesは配列ではなく FileList(配列風)なので、Array.fromで配列にすると扱いやすい- 複数ファイルアップロードや一括処理の入口になる
という点です。
例題①:選んだ画像ファイルをプレビュー表示する
HTML
<input type="file" id="imageInput" accept="image/*">
<img id="preview" alt="プレビュー" style="max-width: 200px; display: block; margin-top: 8px;">
JavaScript(URL.createObjectURL を使うパターン)
const input = document.querySelector("#imageInput");
const preview = document.querySelector("#preview");
input.addEventListener("change", () => {
const file = input.files[0];
if (!file) return;
if (!file.type.startsWith("image/")) {
alert("画像ファイルを選んでください");
return;
}
const url = URL.createObjectURL(file);
preview.src = url;
});
JavaScript流れを整理すると、
ユーザーが画像ファイルを選ぶinput.files[0] から File を受け取るfile.type で画像かどうか軽くチェックURL.createObjectURL(file) で一時 URL を作る
その URL を img.src にセットしてプレビュー
という構成です。
ここで掴んでほしいのは、
「input type=”file” は File を渡してくれるだけ」
「それをどう扱うかは JavaScript 次第」
という感覚です。
例題②:選んだテキストファイルの中身を画面に表示する
HTML
<input type="file" id="textInput" accept=".txt">
<pre id="output"></pre>
JavaScript(FileReader を使う)
const input = document.querySelector("#textInput");
const output = document.querySelector("#output");
input.addEventListener("change", () => {
const file = input.files[0];
if (!file) return;
const reader = new FileReader();
reader.addEventListener("load", () => {
output.textContent = reader.result;
});
reader.addEventListener("error", () => {
console.error("読み込みに失敗しました:", reader.error);
});
reader.readAsText(file, "utf-8");
});
JavaScriptここでの流れは、
input type=”file” で File を受け取る
FileReader で readAsText するload イベントで reader.result に中身の文字列が入る
それを <pre> に表示する
というものです。
「ファイル選択 → File → FileReader → 表示」という一連の流れが
体に入ると、ファイル操作の基礎はほぼクリアです。
重要ポイント:セキュリティと制約をちゃんと理解する
JavaScript は「好きなファイル」を勝手に読めない
<input type="file"> がないと、
JavaScript はユーザーのローカルファイルに一切アクセスできません。
そして、input があっても、
- ユーザーが自分で選んだファイルだけ
- 選んだファイルのパス(C:… など)は基本的に分からない
- そのファイルを勝手に保存し直したり、上書きしたりはできない
という制約があります。
これは、ユーザーのプライバシーと安全のために
ブラウザが絶対に守っているルールです。
開発者としては、
「ユーザーが選んだファイルを一時的に読み、
必要ならサーバーに送る or ブラウザ内で処理する」
という前提で設計する必要があります。
value を直接書き換えても意味はない
<input type="text"> なら input.value = "abc" で値を変えられますが、<input type="file"> の value は特別扱いです。
セキュリティ上の理由から、
JavaScript から任意のファイルパスを value にセットすることはできません。
つまり、
fileInput.value = "C:\\secret.txt"; // こんなことはできない
JavaScriptということです。
「ファイルを選ぶ」のは、
必ずユーザーの操作でなければいけない、というルールがあると覚えておいてください。
重要ポイント:UI としての input type=”file” をどう扱うか
見た目をカスタマイズしたい場合
<input type="file"> はブラウザ標準の見た目なので、
そのままだとデザイン的に浮くことがあります。
よくやるパターンは、
- input を画面から隠す(
display: noneなど) - 代わりにボタンやラベルを表示する
- そのボタンをクリックしたときに
input.click()を呼ぶ
というものです。
HTML:
<input type="file" id="fileInput" style="display:none;">
<button id="selectBtn">ファイルを選択</button>
<span id="fileName">未選択</span>
JavaScript:
const input = document.querySelector("#fileInput");
const btn = document.querySelector("#selectBtn");
const fileName = document.querySelector("#fileName");
btn.addEventListener("click", () => {
input.click(); // 本物の input をクリックさせる
});
input.addEventListener("change", () => {
const file = input.files[0];
fileName.textContent = file ? file.name : "未選択";
});
JavaScriptこうすると、
見た目は自分好みのボタン
実際のファイル選択は隠れた input が担当
という構成になります。
例題③:input type=”file” とドラッグ&ドロップを両方サポートする
実務では、
「クリックして選択」も「ドラッグ&ドロップ」も
両方使える UI がよくあります。
HTML:
<input type="file" id="fileInput" multiple style="display:none;">
<div id="dropzone" style="width:300px;height:150px;border:2px dashed #666;display:flex;align-items:center;justify-content:center;margin-bottom:8px;cursor:pointer;">
クリックまたはファイルをドロップ
</div>
<ul id="fileList"></ul>
JavaScript(ざっくり):
const input = document.querySelector("#fileInput");
const dropzone = document.querySelector("#dropzone");
const fileList = document.querySelector("#fileList");
function handleFiles(files) {
fileList.innerHTML = "";
Array.from(files).forEach(file => {
const li = document.createElement("li");
li.textContent = `${file.name} (${file.size} bytes)`;
fileList.appendChild(li);
});
}
dropzone.addEventListener("click", () => {
input.click();
});
input.addEventListener("change", () => {
handleFiles(input.files);
});
dropzone.addEventListener("dragover", (event) => {
event.preventDefault();
dropzone.style.backgroundColor = "#eef";
});
dropzone.addEventListener("dragleave", () => {
dropzone.style.backgroundColor = "";
});
dropzone.addEventListener("drop", (event) => {
event.preventDefault();
dropzone.style.backgroundColor = "";
handleFiles(event.dataTransfer.files);
});
JavaScriptここでのポイントは、
- ファイルの処理ロジックを
handleFilesにまとめている - input から来ても、ドラッグ&ドロップから来ても、同じ処理を使い回せる
というところです。
input type="file" は「クリックで選ぶ」入口、
ドラッグ&ドロップは「マウスで放り込む」入口、
どちらも最終的には FileList に収束します。
初心者として input type=”file” で本当に掴んでほしいこと
<input type="file"> は「ユーザーにファイルを選んでもらうための唯一の正規ルート」change イベントで input.files(FileList)を受け取るaccept で「選んでほしい種類」をヒントとして出せるmultiple で複数ファイル選択ができる
JavaScript から任意のファイルパスをセットすることはできない(セキュリティ上の制約)
見た目は隠して、ボタン+input.click() でカスタム UI にするのが定番
まずは次の 2 つを、自分の手で書いてみてください。
- テキストファイルを選んで中身を
<pre>に表示する - 画像ファイルを選んで
<img>にプレビュー表示する
これがスムーズに書けるようになったとき、input type="file" は単なるフォーム部品ではなく、
「ユーザーのローカルデータと、あなたの Web アプリをつなぐ入り口」
として、かなり頼もしく感じられるはずです。
