Подтвердить что ты не робот

События распространения событий, наложения и перетаскивания

Я хочу наложить 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>
4b9b3361

Ответ 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.