はじめに
ブラウザからファイルを選択させるためには
<input type="file">
で実現できますが、これ自体はブラウザのデフォルトのUIなのでデザインをあれこれ修正することはできません。
なんとか装飾しようとすると下記のようにlabelを利用する方法が知られています。
<label for="file_upload" style="">
<input type="file" id="file_upload" style="display:none;">
input fileの方は非表示にしてしまい、labelの方で好きにスタイルを設定しつつ、labelの「for」でinputを指定することで連動させるようなイメージです。
この方法は割と一般的に知られている方法なので、ネットで検索してもこの方法を紹介するサイトがたくさんあり、この方法が当たり前のように思っていました。
しかし、mosopadを作成した際にタイミングによってファイルが選択できない謎の現象に襲われました。再現はできるものの、何がトリガーになっているのかがわからず、さらに、labelをダブルクリックすれば対応可能という謎の状況。
あれこれ調べていたところ、そもそもlabelを使う方法はよくないという記事を見つけました。
なるほど、当たり前と信じていたことが、実は非推奨だったということのようです。では、どのように対応すれば良いのか?対応方法を次に記載します。
対応方法
満たしたいのは「input fileを装飾した上で正しく動作させたい」ということです。そして、labelを使うのはよくなさそうなので、代わりにbuttonを使い、buttonをクリックしたらinput fileのクリックが発火するようにします。
<button id="add_photo_button">ファイル選択</button>
<input type="file" id="file_upload" style="display:none">
<script>
$(function() {
$(document).on('click', '#add_photo_button', function(e){
$('#file_upload').click();
});
});
</script>
jQueryを利用した例ですが上記のように実装できます。