そもそもファイルをドラッグ&ドロップする方法は以下の記事が参考になります.
JavaScript - HTML5でファイルをドラッグして読み込むやつ - Qiita
本題
上記の記事はとてもわかりやすく参考になるのだが,タイトルに書いたようなことをすると少しはまる.
どういう事かと言うと以下の用なコードを書いた時にdragleaveイベントがオーバーレイが出たときに発火してしまうのだ.
$('body').on('dragover', function(e){
e.stopPropagation();
e.preventDefault();
$('#overlay').fadeIn(300);
});
$('body').on('dragleave', function(e){
e.stopPropagation();
e.preventDefault();
$('#overlay').fadeOut(300);
});
一瞬オーバーレイが表示されたかと思ったらすぐにまた消えてしまう.
これを解決する方法を探しているとstackoverflowに参考になるものを発見した.
HTML5 dragleave fired when hovering a child element
これの回答の通りにマスクを作ってやるとうまく動く.
ポイントはdragleaveイベントとdropイベントのハンドリングをマスクのイベントリスナーで処理しているところである.
以下にこれを考慮したコードを示す.
var drop_mask = $('<div />').css({
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 0,
display: 'none',
'z-index': 9999
});
$('body').append(drop_mask);
$('body').on('dragover', function(e){
e.stopPropagation();
e.preventDefault();
drop_mask.show();
$('#overlay').fadeIn(300);
});
drop_mask.on('dragleave', function(e){
e.stopPropagation();
e.preventDefault();
drop_mask.hide();
$('#overlay').fadeOut(300);
});
drop_mask.on('drop', function(e){
e.stopPropagation();
e.preventDefault();
drop_mask.hide();
$('#overlay').fadeOut(300);
});
オーバーレイ自体のコードはこんな感じ.
<div id="overlay"></div>
#overlay{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
opacity: 0.8;
display: none;
}