如何立即触发 dragend 事件
How to fire dragend event immediately
我正在尝试解决触发 dragend
event immediately, when dragged outside the draggable area. For example, notice in the following video, there is about a 0.25s delay when dragging the tag outside the draggable area (when inside it, it registers immediately): https://gyazo.com/18d1afc32eb065d1f35896697ef0479e 的问题。
这是 JSFiddle:http://jsfiddle.net/radonirinamaminiaina/zfnj5rv4/。
这个问题大约 7 年前在这里被问到:HTML5 dragend event firing immediately,但是当它被问到时这似乎更像是浏览器限制,我认为我的问题有很大不同。
有没有办法在拖动到可拖动区域之外时立即触发事件?比如在jfiddle的例子中,如果"This div is draggable"被拖到浏览器的左上角,对于它来说'snap back'零延迟?
更新 来自评论中的一个问题:这是我正在尝试做的一个示例,其中有一个来自 table 中的 Pivot table 的 4s 视频30=]:gyazo.com/3ccd1c3abd7f92d3410022a83b5c25b9。基本上,当用户拖动标签时 "outside of the drag zone" 我希望能够立即删除该标签或触发显示标签已被删除的动画。
您可以尝试在删除这样的元素时自己触发 dragend
事件:
document.addEventListener("drop", function( event ) {
event.preventDefault();
// currentTarget refers to document because I added the listener on it.
event.currentTarget.dispatchEvent(new Event('dragend'));
}, false);
我无法测试这是否会删除动画,因为它似乎是由 MacOS 引起的行为?
另请注意,这可能会使事件 dragend
触发两次。
希望对您有所帮助!
您描述的内容与 Chrome 和 Firefox 中跨 Linux 和 Windows(桌面)系统的测试不一致。由于 COVID 情况,我无法轻松访问其他浏览器 + OS 组合(我不完全是 Apple 粉丝),但这是我制作的 fiddle,您可以在其中测试任何其他浏览器这样的组合:
https://jsfiddle.net/websiter/9d7cfbmx/embedded/result/#Result
它如何测试:它测量 drop
和 dragend
事件之间的毫秒差异。它还将它们中的每一个存储到一个数组中,提供当前存储案例的 min
、max
和 avg
值。如您所见,差异在 0.15ms
和 1.75ms
之间变化,平均值为 ~0.5ms
。
因为它是一个实用的原型制作工具,所以我使用 Vue 来 update/display 统计数据,但这根本不会干扰正在测量的事件(您会注意到它们都发生并且是在 Vue 之外测量的并且数据更新发生在 setTimeout()
内,以确保我根本不会干扰测试)。
不幸的是,Firefox 将 performance.now()
值四舍五入为 1ms
,因此它不会为您提供亚毫秒 min
和 max
值,但平均值似乎是一致的与 Chrome 中的那些(实际上在我的测试中略小)。
以上建议您的前提是 dragend
事件存在 250ms
延迟是不准确的,除非这两个事件都延迟了相同的时间。如果是这样,它 将是可见的 。四分之一秒是人眼可以察觉的。
我继续为 250ms
添加了一个可视化测试器到上面的 fiddle。
另请注意:看您的演示视频,您似乎使用的是 Apple 设备,但没有提供有关使用的浏览器的线索。如果非要我猜的话,我会说它是 Safari。
要禁用该动画必须满足两个条件:
- 您必须在
dragover
事件中调用 preventDefault()
(您已经这样做了)
drop
事件需要在 dragend
之前触发(根据 this answer)
为了使第二个条件发生,如果事件的相关目标是 <html>
,您可以在 dragleave
中调度 drop
。我真的没有看到其他选择:
document.addEventListener("dragleave", function(event) {
if (event.relatedTarget.tagName === 'HTML') {
document.dispatchEvent(new Event('drop'));
}
})
注意:通过在拖出 <html>
时调用 drop
,您将打破任何将内容从浏览器拖出到任何其他程序(AFAIK,这是预期用途之一)的情况的研发)。此外,为了确保您只在实际拖出视口时才执行调度,您应该添加此 CSS 位:body { min-height: 100vh; }
.
此外,如前所述,我现在无法在 Mac 上进行测试,因此我不保证此 hack 有效。它应该,但是......这是一个 Apple 实现,你知道吗?就说苹果吧,一切皆有可能。也许是因为它被咬了,谁知道呢? :)
您可以测试 hack here。
如果上面没有隐藏动画,this might。查看 dragend
了解详情。 (这是尝试不预先触发 drop
(不符合原则),而是从 dragend
触发它并重新发送可取消的 dragend
模拟)。恕我直言,值得一试。
这就是我的答案;不知道为什么,但它奏效了!
document.addEventListener("dragover", function( event ) {
event.preventDefault();
}, false);
我正在尝试解决触发 dragend
event immediately, when dragged outside the draggable area. For example, notice in the following video, there is about a 0.25s delay when dragging the tag outside the draggable area (when inside it, it registers immediately): https://gyazo.com/18d1afc32eb065d1f35896697ef0479e 的问题。
这是 JSFiddle:http://jsfiddle.net/radonirinamaminiaina/zfnj5rv4/。
这个问题大约 7 年前在这里被问到:HTML5 dragend event firing immediately,但是当它被问到时这似乎更像是浏览器限制,我认为我的问题有很大不同。
有没有办法在拖动到可拖动区域之外时立即触发事件?比如在jfiddle的例子中,如果"This div is draggable"被拖到浏览器的左上角,对于它来说'snap back'零延迟?
更新 来自评论中的一个问题:这是我正在尝试做的一个示例,其中有一个来自 table 中的 Pivot table 的 4s 视频30=]:gyazo.com/3ccd1c3abd7f92d3410022a83b5c25b9。基本上,当用户拖动标签时 "outside of the drag zone" 我希望能够立即删除该标签或触发显示标签已被删除的动画。
您可以尝试在删除这样的元素时自己触发 dragend
事件:
document.addEventListener("drop", function( event ) {
event.preventDefault();
// currentTarget refers to document because I added the listener on it.
event.currentTarget.dispatchEvent(new Event('dragend'));
}, false);
我无法测试这是否会删除动画,因为它似乎是由 MacOS 引起的行为?
另请注意,这可能会使事件 dragend
触发两次。
希望对您有所帮助!
您描述的内容与 Chrome 和 Firefox 中跨 Linux 和 Windows(桌面)系统的测试不一致。由于 COVID 情况,我无法轻松访问其他浏览器 + OS 组合(我不完全是 Apple 粉丝),但这是我制作的 fiddle,您可以在其中测试任何其他浏览器这样的组合:
https://jsfiddle.net/websiter/9d7cfbmx/embedded/result/#Result
它如何测试:它测量 drop
和 dragend
事件之间的毫秒差异。它还将它们中的每一个存储到一个数组中,提供当前存储案例的 min
、max
和 avg
值。如您所见,差异在 0.15ms
和 1.75ms
之间变化,平均值为 ~0.5ms
。
因为它是一个实用的原型制作工具,所以我使用 Vue 来 update/display 统计数据,但这根本不会干扰正在测量的事件(您会注意到它们都发生并且是在 Vue 之外测量的并且数据更新发生在 setTimeout()
内,以确保我根本不会干扰测试)。
不幸的是,Firefox 将 performance.now()
值四舍五入为 1ms
,因此它不会为您提供亚毫秒 min
和 max
值,但平均值似乎是一致的与 Chrome 中的那些(实际上在我的测试中略小)。
以上建议您的前提是 dragend
事件存在 250ms
延迟是不准确的,除非这两个事件都延迟了相同的时间。如果是这样,它 将是可见的 。四分之一秒是人眼可以察觉的。
我继续为 250ms
添加了一个可视化测试器到上面的 fiddle。
另请注意:看您的演示视频,您似乎使用的是 Apple 设备,但没有提供有关使用的浏览器的线索。如果非要我猜的话,我会说它是 Safari。
要禁用该动画必须满足两个条件:
- 您必须在
dragover
事件中调用preventDefault()
(您已经这样做了) drop
事件需要在dragend
之前触发(根据 this answer)
为了使第二个条件发生,如果事件的相关目标是 <html>
,您可以在 dragleave
中调度 drop
。我真的没有看到其他选择:
document.addEventListener("dragleave", function(event) {
if (event.relatedTarget.tagName === 'HTML') {
document.dispatchEvent(new Event('drop'));
}
})
注意:通过在拖出 <html>
时调用 drop
,您将打破任何将内容从浏览器拖出到任何其他程序(AFAIK,这是预期用途之一)的情况的研发)。此外,为了确保您只在实际拖出视口时才执行调度,您应该添加此 CSS 位:body { min-height: 100vh; }
.
此外,如前所述,我现在无法在 Mac 上进行测试,因此我不保证此 hack 有效。它应该,但是......这是一个 Apple 实现,你知道吗?就说苹果吧,一切皆有可能。也许是因为它被咬了,谁知道呢? :)
您可以测试 hack here。
如果上面没有隐藏动画,this might。查看 dragend
了解详情。 (这是尝试不预先触发 drop
(不符合原则),而是从 dragend
触发它并重新发送可取消的 dragend
模拟)。恕我直言,值得一试。
这就是我的答案;不知道为什么,但它奏效了!
document.addEventListener("dragover", function( event ) {
event.preventDefault();
}, false);