Javascript 如何立即触发dragend事件

Javascript 如何立即触发dragend事件,javascript,browser,dom-events,Javascript,Browser,Dom Events,我正试图解决当被拖到可拖动区域外时立即触发事件的问题。例如,请注意,在下面的视频中,将标记拖动到可拖动区域外时,会有大约0.25秒的延迟(在可拖动区域内时,它会立即注册): 下面是JSFIDLE: 这个问题大约7年前在这里被问到:,但当被问到时,这似乎更像是一个浏览器限制,我认为我的问题有点不同 当事件被拖出可拖拽区域时,是否有办法立即触发事件?例如,在jfiddle示例中,如果将“This div is draggable”拖到浏览器的左上角,它是否会以零延迟“snap back” 根据评论中

我正试图解决当被拖到可拖动区域外时立即触发事件的问题。例如,请注意,在下面的视频中,将标记拖动到可拖动区域外时,会有大约0.25秒的延迟(在可拖动区域内时,它会立即注册):

下面是JSFIDLE:

这个问题大约7年前在这里被问到:,但当被问到时,这似乎更像是一个浏览器限制,我认为我的问题有点不同

当事件被拖出可拖拽区域时,是否有办法立即触发事件?例如,在jfiddle示例中,如果将“This div is draggable”拖到浏览器的左上角,它是否会以零延迟“snap back”


根据评论中的一个问题更新:下面是我尝试做的一个示例,使用Excel透视表中的4s视频:gyazo.com/3ccd1c3abd7f92d3410022a83b5c25b9。基本上,当用户拖动标签“在拖动区域之外”时,我希望能够立即删除该标签或触发显示该标签已删除的动画。

您可以尝试在删除这样的元素时自己触发
dragend
事件:

document.addEventListener(“drop”),函数(事件){
event.preventDefault();
//currentTarget引用文档,因为我在其上添加了侦听器。
event.currentTarget.dispatchEvent(新事件('dragend'));
},假);
我无法测试这是否会删除动画,因为这似乎是由MacOS导致的行为

还要注意,这可能会使事件
dragend
触发两次


我希望这会有帮助

您所描述的与在Chrome和Firefox中测试Linux和Windows(桌面)系统不一致。由于新冠病毒的情况,我无法轻松访问其他浏览器+操作系统组合(我并不完全是一个苹果迷),但我做了一把小提琴,你可以在这里测试任何其他这样的组合:

测试方式:它测量
drop
dragend
事件之间的毫秒差。它还将它们中的每一个存储到一个数组中,该数组提供当前存储案例的
min
max
avg
值。如您所见,差异在
0.15ms
1.75ms
之间变化,平均值为
~0.5ms

因为它是一个实用的原型工具,所以我使用Vue来更新/显示统计数据,但这根本不会干扰正在测量的事件(您会注意到它们都发生在Vue之外,并且在
setTimeout()
中进行数据更新,以确保我根本不会干扰测试)

不幸的是,Firefox将
performance.now()
值舍入
1ms
,因此它不会给出亚毫秒
min
max
值,但平均值似乎与Chrome中的值一致(在我的测试中,实际值略小)

上述所有情况都表明,除非两个事件的延迟时间相同,否则
250ms
延迟
dragend
事件是不准确的。如果是这样,它将是可见的。四分之一秒是人眼可以看到的。这里有一个实用的方法,你可以测试你的理论,我请你训练你的眼睛,以检测延迟:

在浏览器中的两个元素上并排执行触发视觉事件的任何操作,一个延迟,一个未延迟,同时闪烁。在该元素上,您的眼睛将立即看到它在闪烁后更新。在延迟事件中,您很快仍将看到旧位置,然后您将看到它已更新。
因为我们谈论的是250毫秒,所以必须是缓慢的(懒散的)眨眼,但是你会注意到,在仅仅10-20次测试之后,你会非常擅长测试它(用手与眼睛同步)。只要一个延迟,另一个不延迟,它可以是在两个元素并排(即位置、颜色)上容易观察到的任何东西

在您建立了一些信心之后,您能够发现
250ms
延迟,返回测试并在
dragend
事件中检查它。您可能会同意它没有
250ms
延迟

为了让它更简单,我在上面的提琴上添加了一个250毫秒的视觉测试仪

所以,至少到目前为止,看起来你给了我们一个。而且Y问题不存在。如果你不介意我问的话,X的问题是什么


另一个注意事项:看你们的演示视频,你们显然在使用苹果设备,但它并没有给出使用浏览器的线索。如果非要我猜的话,我会说这是狩猎

要禁用该动画,似乎必须满足两个条件:

  • 您必须在
    dragover
    事件上调用
    preventDefault()
    (您已经这样做了)
  • drop
    事件需要在
    dragend
    is时触发(根据)
为了使第二种情况发生,如果事件的相关目标是
,则可以在
dragleave
中调度
drop
。我真的看不到其他选择:

document.addEventListener("dragleave", function(event) {
  if (event.relatedTarget.tagName === 'HTML') {
    document.dispatchEvent(new Event('drop'));
  }
})
注意:当从
中拖出时,通过调用
drop
,您就打破了将内容从浏览器拖出到任何其他程序中的情况(当然,这是D&D的预期用途之一)。另外,为了确保仅在实际从视口中拖出时才执行分派,应该添加以下CSS位:
body{min height:100vh;}

另外,正如前面提到的,我现在没有办法在Mac上进行测试,所以我不能保证这个黑客程序能正常工作。应该,但是。。。这是一个苹果的实现,你知道吗?让我们只说,对于苹果来说,任何事情都是可能的。也许是因为它被咬了,谁知道呢?:)

<
document.addEventListener("dragover", function( event ) {
    event.preventDefault();
}, false);