状況
input type="file"
を使用してファイルをアップロードする.- 見た目は label タグを使用して整え,input 要素は見えないようにした.
- ファイルを選択したらフォームの見た目を変更したい.
問題点
- JavaScript を用いてスタイルを適用すれば見た目の変更はできる.
- 今回は CSS だけでなくタグの構成も変更しなければならない.
- input 要素を変更する場合,選択したファイルを変更後の input 要素に再設定する処理が必要になるが,セキュリティ上問題となる.
解決策
フォームの見た目を構成する要素を input 要素を分離しておく.画面に表示される label 要素を JavaScript でまとめて書き換えれば良い.
input 要素は非表示となっているため,form 要素内の何処かにあれば問題ない.
実装例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#file {
display: none;
}
#form_labels {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
#form_labels label {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 100px;
border: 1px solid black;
cursor: pointer;
}
#form_labels label p {
font-size: 20px;
}
#new_label {
border: 1px solid black;
background-color: #ccc;
}
</style>
</head>
<body>
<form action="">
<input type="file" name="file" id="file">
<div id="form_labels">
<label for="file">
<p>upload</p>
</label>
</div>
</form>
<script>
// 要素の取得
const file = document.querySelector('#file');
const form_labels = document.querySelector('#form_labels');
// 変更後の label 要素(適当)
const newLabel = [
`<label for="file" id="new_label">`,
`<p>file added.</p>`,
`<p>upload more</p>`,
`</label>`,
].join('');
// ファイル選択時にラベル部分のみを変更
file.addEventListener('change', () => {
form_labels.innerHTML = newLabel;
})
</script>
</body>
</html>
所感
- CSS の変更や input 要素含めての変更では対応できなかったので,別の方法を考えた.
- AI に訊いても↑の路線で出力が返ってきたため解決できず.
- 自分で考えることがとても大事だった.
以上だ( `・ω・)b