gpt4 book ai didi

javascript - 如何在窗口外拖动时检测Firefox中的dragleave事件

转载 作者:IT王子 更新时间:2023-10-29 03:13:33 25 4
gpt4 key购买 nike

当拖动到窗口外时,Firefox 没有正确触发 dragleave 事件:

https://bugzilla.mozilla.org/show_bug.cgi?id=665704

https://bugzilla.mozilla.org/show_bug.cgi?id=656164

我正在尝试为此开发一个解决方法(我知道这是可能的,因为 Gmail 正在这样做),但我唯一能想到的似乎真的很老套。

一种知道何时拖动到窗口外的方法是等待 dragover 事件停止触发(因为 dragover 在拖放操作期间不断触发) .我是这样做的:

var timeout;

function dragleaveFunctionality() {
// do stuff
}

function firefoxTimeoutHack() {
clearTimeout(timeout);
timeout = setTimeout(dragleaveFunctionality, 200);
}

$(document).on('dragover', firefoxTimeoutHack);

这段代码本质上是一遍又一遍地创建和清除超时。除非 dragover 事件停止触发,否则不会达到 200 毫秒超时。

虽然这可行,但我不喜欢为此目的使用超时的想法。感觉不对。这也意味着在“dropzone”样式消失之前会有轻微的滞后。

我的另一个想法是检测鼠标何时离开窗口,但在拖放操作期间,通常的做法似乎不起作用。

有没有人有更好的方法来做到这一点?

更新:

这是我使用的代码:

 $(function() {
var counter = 0;
$(document).on('dragenter', function(e) {
counter += 1;
console.log(counter, e.target);
});
$(document).on('dragleave', function(e) {
counter -= 1;
console.log(counter, e.target);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Open up the console and look at what number is reporting when dragging files in and out of the window. The number should always be 0 when leaving the window, but in Firefox it's not.</p>

最佳答案

我找到了解决方案。问题不在于 dragleave 事件没有触发;相反,dragenter 事件在第一次将文件拖到窗口中时触发了两次(此外,有时在拖动到某些元素上时)。我最初的解决方案是使用计数器来跟踪最终 dragleave 事件何时发生,但 dragenter 事件的两次触发打乱了计数。 (你问我为什么不能只听 dragleave?好吧,因为 dragleave 的功能与 mouseout 非常相似,它不仅在离开元素时触发,而且在进入子元素时触发。因此,当 dragleave 触发时,你的鼠标可能非常我们仍然在原始元素的范围内。)

我提出的解决方案是跟踪触发了哪些元素 dragenterdragleave。由于事件向上传播到文档,因此在特定元素上监听 dragenterdragleave 不仅会捕获该元素上的事件,还会捕获其子元素上的事件。

因此,我创建了一个 jQuery 集合 $() 来跟踪在哪些元素上触发了哪些事件。每当 dragenter 被解雇时,我都会将 event.target 添加到集合中,而当 dragleave 发生时,我会从集合中删除 event.target。这个想法是,如果集合为空,则意味着我实际上已经离开了原始元素,因为如果我改为输入子元素,至少有一个元素(子元素)仍将位于 jQuery 集合中。最后,当 drop 事件被触发时,我想将集合重置为空,以便在下一个 dragenter 事件发生时准备好。

jQuery 还节省了很多额外的工作,因为它会自动进行重复检查,所以 event.target 不会被添加两次,即使 Firefox 错误地双重调用 dragenter 也是如此。

无论如何,这是我最终使用的代码的基本版本。如果其他人有兴趣使用它,我已经将它放入一个简单的 jQuery 插件中。基本上,您在任何元素上调用 .draghover,当第一次拖入该元素时会触发 draghoverstart,当拖动实际离开时会触发 draghoverend

// The plugin code
$.fn.draghover = function(options) {
return this.each(function() {

var collection = $(),
self = $(this);

self.on('dragenter', function(e) {
if (collection.length === 0) {
self.trigger('draghoverstart');
}
collection = collection.add(e.target);
});

self.on('dragleave drop', function(e) {
collection = collection.not(e.target);
if (collection.length === 0) {
self.trigger('draghoverend');
}
});
});
};

// Now that we have a plugin, we can listen for the new events
$(window).draghover().on({
'draghoverstart': function() {
console.log('A file has been dragged into the window.');
},
'draghoverend': function() {
console.log('A file has been dragged out of window.');
}
});

没有 jQuery

要在没有 jQuery 的情况下处理这个问题,您可以这样做:

// I want to handle drag leaving on the document
let count = 0
onDragEnter = (event) => {
if (event.currentTarget === document) {
count += 1
}
}

onDragLeave = (event) => {
if (event.currentTarget === document) {
count += 0
}

if (count === 0) {
// Handle drag leave.
}
}

关于javascript - 如何在窗口外拖动时检测Firefox中的dragleave事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10253663/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com