Прошло довольно много времени после того, как был задан этот вопрос, и было предложено множество решений (включая некрасивые хаки).
Мне удалось решить ту же проблему, с которой я столкнулся недавно, благодаря ответу в этом ответе и подумал, что это может быть полезно для тех, кто заходит на эту страницу.Вся идея заключается в том, чтобы хранить evenet.target
в ondrageenter
каждый раз, когда он вызывается на любом из родительских или дочерних элементов.Затем в ondragleave
проверьте, равна ли текущая цель (event.target
) объекту, который вы сохранили в ondragenter
.
Единственный случай, когда эти два значения совпадают, это когда ваше перетаскивание покидает окно браузера.
Причина, по которой это работает нормально, заключается в том, что мышь покидает элемент (скажем, el1
) и вводит другой элемент (скажем, el2
), сначала вызывается el1.ondragenter
, а затем el2.ondragleave
.Только когда перетаскивание покидает / входит в окно браузера, event.target
будет ''
в el1.ondragenter
и el2.ondragleave
.
. Вот мой рабочий пример.Я протестировал его на IE9 +, Chrome, Firefox и Safari.
(function() {
var bodyEl = document.body;
var flupDiv = document.getElementById('file-drop-area');
flupDiv.onclick = function(event){
console.log('HEy! some one clicked me!');
};
var enterTarget = null;
document.ondragenter = function(event) {
console.log('on drag enter: ' + event.target.id);
enterTarget = event.target;
event.stopPropagation();
event.preventDefault();
flupDiv.className = 'flup-drag-on-top';
return false;
};
document.ondragleave = function(event) {
console.log('on drag leave: currentTarget: ' + event.target.id + ', old target: ' + enterTarget.id);
//Only if the two target are equal it means the drag has left the window
if (enterTarget == event.target){
event.stopPropagation();
event.preventDefault();
flupDiv.className = 'flup-no-drag';
}
};
document.ondrop = function(event) {
console.log('on drop: ' + event.target.id);
event.stopPropagation();
event.preventDefault();
flupDiv.className = 'flup-no-drag';
return false;
};
})();
А вот простая HTML-страница:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Multiple File Uploader</title>
<link rel="stylesheet" href="my.css" />
</head>
<body id="bodyDiv">
<div id="cntnr" class="flup-container">
<div id="file-drop-area" class="flup-no-drag">blah blah</div>
</div>
<script src="my.js"></script>
</body>
</html>
При правильном оформлении я сделал, чтобы сделатьвнутренний div (# file-drop-area) намного больше, когда файл перетаскивается на экран, чтобы пользователь мог легко поместить файлы в нужное место.