inputタグではファイルをアップロードすることができますが、ファイル名しか表示されません。
アップロードした画像が見れたり、容量など表示したいので、JavaScriptを使って表示させる方法を紹介します。
共通のHTML・CSS
基本的にJavaScriptを書いていくので、それに使うHTML・CSSを設定します。
inputタグにuploadというIDを付け、そこにファイルをアップロードされたら、result,previewというIDそれぞれに情報を出していきたいと思います。
ファイル名はinputを使うだけで自動で表示されます。
ただ表示幅によっては省略されてしまうので、widthを100%にして出来るだけ省略せずに表示するようにしております。
<input id="upload" type="file">
<div><span id="result"></span></div>
<div id="preview"></div>
#upload, #preview * {
width: 100%;
}
アップロードファイルの容量を自動表示
ファイル容量を出す。
アップロードしたファイルが変われば動く処理にし、ファイル情報を取得します。
ひとまず容量を表示したいので、fileのsizeをresultに表示させます。
ただ単位がbyteになっているので、例えば10MBだと10485760byteとなって非常に見づらくなってしまうので、最適な単位で出せるようにしたいと思います。
const setChangeFile = () => {
document.getElementById('upload')?.addEventListener('change', (event) => {
const {files} = event.target;
for (const file of files) {
document.getElementById('result').innerText = file.size;
}
});
}
最適な単位で出す
関数displayBiteを作成し、1024で割り切れないところまでやっていき表示させます。
単位はbyteからKB,MB,GB,TB,PB,EB,ZB,YBと続いていくようです。
後半はなかなか使うことはないと思いますが、念のため設定しております。
for (const file of files) {
displayUnit(file);
}
function displayUnit(file) {
const {size} = file;
let displayBite = size;
let displayUnitIndex = 0;
const unit = ['byte', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
while (displayBite / 1024 > 1) {
displayBite = displayBite / 1024;
displayUnitIndex++;
}
document.getElementById('result').innerText = displayBite + unit[displayUnitIndex];
}
プレビュー表示
設定と画像表示
displayUnit関数と同じ個所に、新たにpreviewFile関数を作ります。
FileReaderを使い、アップロードしたファイルを読み込み、読み込み完了後に表示させます。
基本的処理は同じですが、ファイルによって表示方法は若干違います。
画像であればimgタグを使いますが、動画はvideoタグを使います。
for (const file of files) {
previewFile(file);
displayUnit(file);
}
function previewFile(file) {
const previewId = document.getElementById('preview');
const fileReader = new FileReader();
fileReader.onload = (event) => {
const {result} = event.target;
const {type} = file;
if (type.includes('image')) {
const img = document.createElement('img');
img.src = result;
previewId.appendChild(img);
}
}
fileReader.readAsDataURL(file);
}
再アップロード時のプレビュー注意
実際に再アップロードしたらわかりますが、前の画像が残ったままプレビュー表示されてしまうので、再アップロードされた場合は消す必要があります。
なので
const previewId = document.getElementById('preview');
previewId.innerHTML = '';
動画
controlsをtrueにしなくてもいいのですが、ぱっとみ画像か動画か判断難しいので、コントロールを付けて動画だとわかるようにしております。
if (type.includes('video')) {
const video = document.createElement('video');
video.src = result;
video.controls = true;
previewId.appendChild(video);
}
if (type.includes('pdf')) {
const object = document.createElement('object');
object.data = result;
object.height = '800px';
previewId.appendChild(object);
}
まとめ
inputタグでアップロードしたファイル情報を表示する方法をまとめていきました。
addEventListenerのchangeを使うことで、ファイル情報を取り出すことができます。
プレビューはFileReaderを使う必要があるのと、拡張子によってタグを使い分ける必要があります。
少し複雑ですが参考になると嬉しいです。
また今回は触れていませんが、実は何でもアップロードできてしまうのは情報漏洩をしてしまう原因になります。
これについては別記事で紹介しているので、一度目を通すのをオススメしております。