【问题标题】:Is there no Event.fromElement in a dragenter/dragover event?dragenter/dragover 事件中没有 Event.fromElement 吗?
【发布时间】:2011-12-17 20:32:01
【问题描述】:

我正在玩完整形式的拖放(所以没有即时上传)。我虽然用文件悬停在一小部分会突出显示某个字段集。输入dragoverdragenter 事件(和dragleave 等)。

事实证明,这并不是一个很小的部分。小提琴:http://jsfiddle.net/rudiedirkx/epp74/

试试看:拖动一个字段集并移动一下。第一个over 触发字段集的dragenter 事件(字段集为黄色)。之后的移动(在同一个字段集中)会触发 dragenters 和 dragleaves(字段集不再是黄色),这很糟糕。

这就是为什么我想做很久以前 IE 为 mouseovermouseout 制作的东西:mouseentermouseleave(它们只触发一次)。对于拖动事件,完全相同的事情适用:它们应该以完全相同的方式只触发一次。 JS 库通过使用 Event.fromElementEvent.toElement 来欺骗这些 IE 事件(并将它们与事件所有者元素进行比较)。 (详情请参阅jQueryMootools 来源。)

为了使拖动事件相同,我需要相同的 fromElementtoElement。您可以在 Fiddle 中看到,我尝试了,但我找不到它们。

有人知道他们在哪里吗?为什么它们不可用?

我主要使用 Chrome,它在 dragenter 事件中没有 fromElement,但在 dragleave 事件中确实toElement。在 Firefox 中情况稍差(但更合乎逻辑):两者都是空的。

非常欢迎任何和所有想法。

编辑
a little more debugging 之后,我发现dragleave 中的Chrome 的toElement 并不总是正确的。它永远不会比this“更大”,但有时它应该是:当我将字段集 (this) 留给其父表单 (toElement) 时。当我这样做时,thistoElement 都是字段集(这是不正确的,对吧?)。

编辑解决方案:
我最终得到了这样的结果:http://jsfiddle.net/rudiedirkx/Lwd3md71/ 忽略事件中的元素,并使用事件坐标来查找鼠标下的元素。为了使它在每个动画帧中触发一次 max,它使用 requestAnimationframe,结果为 31-59 fps。

【问题讨论】:

  • 我只是略过了你的问题,但你是在寻找事件的 srcElement 属性吗?
  • 不。我正在寻找正确的 toElement。要检测离开字段集的拖动,我需要将 toElement 放在字段集之外(如<form><body>)。但它总是空的......非本机mouseenter和mouseleave事件(由JS库创建)使用它从mouseover和mouseout创建mouseenter和mouseleave。我试图对 dragenter 和 dragleave 做同样的事情。我需要 toElement 和/或 fromElement 。诡异的。一种可能的解决方案(?)是将侦听器附加到父元素(甚至<body>)...
  • 啊,我明白了。对不起,做这样的海鸥!
  • e.relatedTarget 在 Chrome 23 中始终为 null...
  • 这可能无法回答您的具体问题,但这是您的小提琴以我认为您希望的方式工作:jsfiddle.net/epp74/19

标签: javascript html events drag-and-drop


【解决方案1】:

Firefox 提供relatedTarget 事件属性,但 Chrome 和 Safari 不提供。遗憾的是,这个问题已经公开了几年,因为这个Chrome bug 和这个Webkit bug

编辑:该问题已在 Chrome 中修复。

【讨论】:

  • 它存在,但它总是空的。火狐也是一样。不过,自 11 年 12 月以来,他们可能已经改变了这一点。
  • 你是对的。 Firefox 没有toElementfromElement,但它确实有一个有效的relatedTarget。 Chrome 有所有和没有工作。 jsfiddle.net/rudiedirkx/epp74/21
  • 如果你仍然感兴趣,这就是我最终得到的:jsfiddle.net/rudiedirkx/Lwd3md71
  • Chrome 现在也提供relatedTarget,但 Safari 不提供。
【解决方案2】:

有一种方法可以为“dragleave”事件伪造relatedTarget,即从伴随的“dragenter”事件中设置一个变量——因为dragleave总是在dragenter之前,所以在后者中设置的变量将可用对前者:

var relatedTarget = null;

document.addEventListener('dragenter', function(e)
{
    relatedTarget = e.target;

}, false);
document.addEventListener('dragleave', function(e)
{
    console.log('target = ' + e.target + ' relatedTarget = ' + relatedTarget);

}, false);

它不会反过来工作,但如果你以这种方式使用它,你真的不需要 dragenter 来做任何其他事情 - 即单独的 dragleave 足以告诉你鼠标何时移动或完全移动出,一个特定的元素。

【讨论】:

  • 我将尝试在我的 JS 库中伪造 relatedTarget。这听起来不对,但它可能会奏效。 Chrome 以一种方式工作,因此它只需要以另一种方式工作。 (让我们希望这是可能的方式。)我会让你知道的。谢谢。
  • 我不确定 JS 库如何概括这一点,但它可以在自定义代码中完美运行:webblocks.nl/tests/dragenterleave.html 也比使用 Firefox 的工作方法快得多 =) 谢谢!
  • 这有点像 hack,是的,但它可以解决问题。在我自己的实现中,我维护一个“选择”对象,其中包含当前正在拖动的元素的详细信息(或者当没有拖动任何内容时为 null)。该对象还具有以这种方式实现的 .related 属性,以及从中推断出的 .droptarget 属性。然后,每当 droptarget 发生变化时,我都会使用 dragleave 来更新拖动幻影(即显示有效或无效的图标,因为 dropEffect 和 effectAllowed 不会影响光标)。
  • 如果您仍然感兴趣,这就是我最终得到的:jsfiddle.net/rudiedirkx/Lwd3md71
猜你喜欢
  • 2015-12-17
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 2010-10-08
  • 2012-06-19
  • 2015-11-02
  • 1970-01-01
  • 2015-01-01
相关资源
最近更新 更多