События распространения событий, наложения и перетаскивания
Я хочу наложить div над окном просмотра, когда пользователь перетаскивает файл в окно.
Однако у меня возникают проблемы с распространением событий. Когда я устанавливаю оверлей на display: block
, он снова запускает событие dragleave
, а затем еще один dragenter
, а затем еще один dragleave
, поэтому он всегда находится в состоянии post-dragleave. Конечно, я вызываю e.stopPropagation()
и e.preventDefault()
для объекта события, но, похоже, это не имеет значения.
Вывод console.log() при перетаскивании чего-либо над окном:
dragenter
dragenter
dragleave
dragenter
dragleave
css. #overlay
по умолчанию установлен на display: none
, но покажет, имеет ли body
класс dragenter
:
body {
position: absolute;
height: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 0;
}
#overlay {
position: absolute;
height: auto;
width: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url(bg.png) repeat-x top right, url(bg.png) repeat-x bottom left, url(bg.png) repeat-y top right, url(bg.p
ng) repeat-y bottom left;
display: none;
}
body.dragenter #overlay {
display: block;
}
javascript. Добавьте класс 'dragenter' в dragenter и удалите его на dragleave:
$(document).on('dragenter', function (e) {
e.stopPropagation();
e.preventDefault();
console.log('dragenter');
$(document.body).addClass('dragenter');
});
$(document).on('dragleave', function (e) {
e.stopPropagation();
e.preventDefault();
console.log('dragleave';
$(document.body).removeClass('dragenter');
});
html:
<body>
<div id="overlay">...</div>
...
</body>
Ответы
Ответ 1
Благодаря Scottux это привело меня на правильный путь.
Только проблема заключалась в том, что он также перекрывал остальную часть страницы, поэтому ни один из элементов или входов не был доступен для кликов. Мне пришлось скрывать #dragOverlay по умолчанию с "display: none" и отображать его на этом событии
// Display an overlay when dragging a file over
$('*:visible').live('dragenter', function(e) {
e.stopPropagation();
$('body').addClass('drag-enter');
});
Ответ 2
Ваш оверлей занимает весь размер документа, когда вы перетаскиваете его, он заполняет свое пространство, и ваша мышь эффективно выводится из тела и теперь находится поверх наложения. Это вызывает цикл mouseleave/mouseenter. Чтобы добиться того, что вам нужно, вы можете привязать событие к прозрачному наложению с высоким z-индексом над видимым наложением, которое имеет более низкий z-индекс. Это сохранит событие в самом высоком элементе.
Пример:
http://jsfiddle.net/scottux/z7yaB/
Ответ 3
var dropZone = function() {
var self = this;
this.eTimestamp = 0;
this.showDropZone = function(e) {
e.stopPropagation();
e.preventDefault();
if (self.eTimestamp + 300 < e.timeStamp) {
$("#coverDropZone").show();
self.eTimestamp = e.timeStamp;
}
return false;
}
this.hideDropZone = function(e) {
e.stopPropagation();
e.preventDefault();
if (self.eTimestamp + 300 < e.timeStamp) {
$("#coverDropZone").hide();
self.eTimestamp = e.timeStamp;
}
return false;
}
this.showImage = function(e) {
e.stopPropagation();
e.preventDefault();
console.log(e);
return false;
}
document.addEventListener('dragenter', self.showDropZone, false);
document.addEventListener('dragleave', self.hideDropZone, false);
document.addEventListener('drop', self.showImage, false);
}
Ответ 4
Простое решение вместо использования dragenter использует dragover
DragOver
Это событие запускается, когда мышь перемещается по элементу, когда происходит перетаскивание. В большинстве случаев операция, выполняемая во время прослушивателя, будет такой же, как событие dragenter.