这是我的代码:
var dragStart = _.debounce(function () {
console.log("START");
$dropIndicator.appendTo(document.body).show();
}, 10, {
leading: true,
trailing: false
});
var dragStop = _.debounce(function () {
console.log("STOP");
$dropIndicator.hide();
}, 10, {
leading: false,
trailing: true
});
$(window)
.on('dragover', function (ev) {
ev.preventDefault();
ev.originalEvent.dataTransfer.dropEffect = 'copy';
dragStop.cancel();
dragStart();
})
.on('dragleave', function (ev) {
ev.preventDefault();
dragStop();
})
.on('drop', function (ev) {
ev.preventDefault();
dragStop();
uploadFiles(ev.originalEvent.dataTransfer.files);
});
如果我将文件拖到窗口顶部,我会看到我的掉落指示符。但是,当在窗口上移动文件时(不会将鼠标从窗口移开),我看到“STOP”会定期调用。
在“拖动的元素或文本选择留下有效的放置目标”之前,不应该调用 MDN says dragleave
- 但我的目标是窗口,我从未离开过。
为什么要被召唤?这会导致我的掉落指示器闪烁,或者更糟糕的是,有时根本没有捕获掉落事件。
我把去抖动放在那里以减轻问题,但无论有没有去抖,它仍然是一个问题。
答案 0 :(得分:2)
我尝试了几个不同的库,但它们都没有特别好用。这是我提出的最佳解决方案:
var $dropIndicator = $('#drop-indicator');
let dragOpen = false;
let dragElements = new Set();
let closeTimer = null;
function showDragIndicator() {
clearTimeout(closeTimer);
if(!dragOpen) {
$dropIndicator.appendTo(document.body).show();
dragOpen = true;
}
}
function hideDragIndicator() {
clearTimeout(closeTimer);
closeTimer = setTimeout(() => {
hideDragIndicatorNow();
}, 100);
}
function hideDragIndicatorNow() {
if(dragOpen) {
$dropIndicator.hide();
dragOpen = false;
dragElements.clear();
}
}
$(window)
.on('drop', function(ev) {
ev.preventDefault();
hideDragIndicator();
uploadFiles(ev.originalEvent.dataTransfer.files);
})
.on('dragover', function(ev) {
ev.preventDefault();
showDragIndicator();
})
.on('dragenter', function(ev) {
ev.preventDefault();
dragElements.add(ev.target);
showDragIndicator();
})
.on('dragleave', function(ev) {
ev.preventDefault();
dragElements.delete(ev.target);
if(dragElements.size === 0) {
hideDragIndicator();
}
})
.on('mousemove', function(ev) {
ev.preventDefault();
hideDragIndicatorNow();
});
适用于Ubuntu的Firefox和Chrome以及Windows上的Windows和IE11。
Firefox Windows有一个错误,当您在窗口上拖动文件然后再次退回时,dragleave
事件不会触发,这就是为什么我添加了mousemove
事件以便将鼠标移回窗口时,拖放指示器至少会清除。
隐藏延迟是必要的,以防止一些闪烁,即使我已经跟踪触发进入/离开的所有元素,他们似乎发射太多。
您must绑定dragover
事件,以便在IE中使用。