ChromeでエクスプローラからフォルダをD&Dする

WebページにフォルダをD&Dしたいと思って調べたのでメモを残しておく。


実現したいこと

  • エクスプローラからWebページにフォルダをD&Dしてアップロードしたい
  • ドロップターゲットはデザインしたい
  • Chromeで動けばよい

結論

  • フォルダのD&Dには<input type="file" webkitdirectory directory> を使う
  • ドロップターゲットはdivで好きにデザインする
  • デザインした<div>の上にtype="file"のinput要素をサイズ指定、opacity:0で配置する

試行錯誤の跡

まず、Chromeのinput type="file"にはエクスプローラからファイルをD&Dできる。すばらしいですねChrome。もうファイル選択ダイアログを開くことはない。

ここ によると webkitdirectory 属性を指定することでinput type="file"にフォルダを指定できるようだ。実際にはフォルダ内のファイルがすべて展開されて指定される。大量にファイルを含むフォルダを指定すると大変なことになるけどまぁそれはそれ。

 <input type="file" name="img" class="file" webkitdirectory directory>

次に input type="file" の見た目を変える方法を探す。ここらをみるとCSSでinputを透明にして上に重ねるのがいいらしい。前後関係を指定するのがcssのz-index。positionでrelativeやabsoluteを駆使する。よくわからないのでそのまま使わせてらおう。

でもこれだとinputのサイズを予測できない、と思ったら width, height指定が効くらしい。これで特定の領域のどこでもDropを有効にできる。どこをクリックしてもフォルダ選択ダイアログが表示される。

 <input type="file" name="img" class="file" webkitdirectory directory style="width: 100%; height: 100px">

あとはinputの下においたdivをデザインするとできあがり。D&Dした後はHTML5 のFile APIで好きに操作できる。

HTMLソースは次のようになった。

<html>
<head>
<style>
div.fileinputs {
 position: relative;
}

div.fakefile {
 position: absolute;
 top: 0px;
 left: 0px;
 z-index: 1;
 
 background-color: lightcoral;
 width: 100%;
 height: 100px;
 text-align: center;
 line-height: 100px;
 -webkit-border-radius: 10px;
}
input.file {
 position: relative;
 opacity: 0;
 z-index: 2;
 
 width: 100%;
 height: 100px;
}
</style>
</head>
<body>
<div class="fileinputs">
	<input type="file" name="img" class="file" webkitdirectory directory>
	<div class="fakefile">ここにフォルダをD&Dしてください</div>
</div>
</body>
</html>

inputのbackground-colorやopacityの値を変えると動作がよくわかる。

jQuery File Uploadも見たけどどこを変えればいいかわからなかった。