ふつうにvalueを書くことができない<input type="file">ですが、ブラウザによっては動的な設定もほぼ自由に行えることが判明しました。
<input type="file">へ値を設定する
入力するものがファイルである以上、<input type="file">に対してvalueは(空にするvalue = ''を除けば)使えないのですが、別ルートとしてfilesというプロパティがあります(MDN)。ここには選択したファイルのリスト(multipleでなければ1つだけ)が入ったFileListオブジェクトが入っていて、また代入することで設定が可能です。
FileListって、何?
ところが、filesに代入するものもFileListオブジェクトでなければならず、代わりにFileの配列を持ってきてもエラーになります。しかも、new FileListも動かないため、一見すると他の<input type="file">から持ってくる、ぐらいの動作しかできないようにも見えます。実際、昔はそうでした。
裏口から作る~DataTransfer
ここで登場するのがDataTransferです。これは、ドラッグアンドドロップで動かしているデータを持つためのオブジェクトです。ファイルを投げ込むような動作も存在する以上、このオブジェクトもfilesとしてFileListを持っています。
そして、どういうわけか、DataTransferはnewできます。なので、DataTransfer経由でFileListをゼロから作ることが可能となります。
const dt = new DataTransfer();
dt.items.add(file);
const list = dt.files;
なお、iOS(とIE)はこの方法に対応していませんので、要注意です(Can I use)。
動作例
<input type="file" multiple>で一気に選んだファイルを、1つ1つ<input type="file">に分配するような例を実装しました。
See the Pen DataTransfer経由でFilesを作る by Jkr2255 (@jkr2255) on CodePen.
その他
DataTransfer経由でFileListの作成が可能となったため、new FileListができないことが有害無益となってしまい、これも可能とする動きもあるようです。