先に結論だけ
input type="file"要素は選択されたファイルの情報を保存します。まったく同じファイルを選択した場合、input要素はchangeおよびinputイベントを発行しません。input要素のvalue属性に"" 空文字
を設定すると選択状態がクリアされ、input要素は再度イベントを発行します。
はじめに
この記事はinput type="file"
要素の選択状態とイベント発行について記録、共有するためのものです。
シングルページアプリケーションで、fileタイプのinput要素をファイルオープンコマンドとして利用したところ、イベントが発行されず詰まりました。fileタイプのinput要素について誤解していた点と、解決手順を整理します。
問題発生の経緯
ローカルファイルを開き、編集を加えるシングルページアプリケーションを開発します。
ファイルオープンコマンドとしてfileタイプのinput要素を利用します。input要素のchangeイベントをトリガーにしてファイルを開き編集します。
編集状態を破棄してもう一度ファイルを開こうとしたとき、input要素からイベントが発行されないことに気がつきました。この問題は、編集状態を破棄する前と後で同じファイルを開くときのみ発生し、別のファイルを開くときは正常に動作します。
問題の分析と解決
この問題は、同一ファイルをinput要素に連続して与えるとイベントが発行されない事が原因です。
マルチページアプリケーションの場合
マルチページアプリケーションでは、ユーザーはお問い合わせフォームのような一連のinputフォームを入力し、最後にsubmitボタンを押します。JavaScriptはsubmitボタンが押されてから、すべてのフォームの入力値をあつめてサーバーに送信し、送信前ページなど次のページに遷移します。
このページ遷移のタイミングでinput要素はすべて破棄されるため、開発者はフォームの再利用を考える必要がありません。ページの遷移に伴いフォームがクリアされる点を失念したため、この問題が発生しました。
シングルページアプリケーションの場合
シングルページアプリケーションでは、ユーザーがinput要素に値を入力したらJavaScriptはイベントに応じてそのたびに反応を返します。input要素は、入力値が再び必要になった場合に備えてvalue属性に入力値をため込んでいます。input要素はvalue属性値と同じ値を入力された場合、changeおよびinputイベントを発行しません。
解決方法
ため込んだ値をクリアすれば、input要素は再びイベントを発行します。fileタイプのinput要素の場合、value属性に空文字""
を代入すれば値がクリアされます。
以上、ありがとうございました。
参考記事