【问题标题】:Why is the mouseenter part of this hover executing, but not the mouseleave?为什么执行此悬停的 mouseenter 部分,而不是 mouseleave?
【发布时间】:2012-07-09 19:09:01
【问题描述】:

我正在使用 this syntax option 进行 jquery 悬停。

这是我的代码:

$('mySelector')
    .hover(
        function(){
            $(this).html('<img src="images/myImage2.png" height="23" width="24" />');
        },
        function(){
            $(this).html('<img src="images/myImage1.png" height="23" width="24" />');
        }
    );

mySelector 引用的元素的原始文本是 mouseleave 选项 - $(this).html('&lt;img src="images/myImage1.png" height="23" width="24" /&gt;');

第一个处理程序,用于 mouseenter/mouseover,工作正常。但是第二个处理程序,用于 mouseleave/mouseout(应该恢复原始图像),永远不会执行。当我在firebug中跟踪它时,触发了mouseover事件,但没有到达第二个“function()”。

编辑:

为了清楚起见,我的 html 代码是这样的:

<div id="results">
   <span class="imageClass"><img src="images/myImage1.png" height="23" width="24" /</span>
</div>

然后我的选择器是"#results .imageClass"

【问题讨论】:

  • 你能在 jsfiddle 上重现这个问题吗?
  • 检查我发布的小提琴
  • @zerkms - 我现在似乎无法使用 jsfiddle,当我这样做时,我会尝试重现它。
  • @froadie 你能发布所有相关元素的 HTML 结构吗?

标签: jquery hover mouseevent


【解决方案1】:

这个问题的原因可能是 触发mouseenter 事件的元素(即&lt;img&gt; 节点)在触发mouseleave 事件之前从 DOM 中删除。该事件由mySelector 的事件处理程序捕获和处理,但&lt;img&gt; 是事件的实际来源。因此,mouseleave 事件不会被新的&lt;img&gt; 触发是有道理的,因为鼠标从一开始就没有进入它。

澄清:事件处理程序绑定到的DOM节点(mySelector)与首先触发事件的节点(&lt;img&gt;)不同。因为&lt;img&gt; 没有针对此事件的自己的处理程序,所以事件将bubble up through the DOM tree 直到遇到可以处理的节点(在本例中为mySelector)。

事实证明,adeneo's solution 确实有效,尽管他/她的回答不准确。这是一个工作示例:jsbin.com/ikolog

有用的资源:

【讨论】:

  • 谢谢你的回答,我会试试这个,让你知道。但是为什么“从 DOM 中删除了触发 mouseenter 事件的元素”?触发事件的不是图像,而是它周围的跨度。
  • @froadie:该事件确实由&lt;span&gt;处理,但事件的实际起源——触发它的元素——很可能是@ 987654340@。由于&lt;img&gt; 没有事件处理程序,因此事件在DOM 中“冒泡”,直到遇到一个元素。看看MDN docs on DOM events
  • 谢谢,这确实解决了问题!但是,如果问题是你所说的,为什么我的 mouseenter 事件即使在原始 img 标签被删除后仍被触发?
  • (感谢“他/她” :) 为什么每个人总是认为程序员是他? ;) )
  • @froadie:就像我说的,事件处理程序仍然绑定到&lt;span&gt;。这并没有改变,所以新的&lt;img&gt; 将触发另一个mouseenter 事件(它自己的一个),这将(再次)被&lt;span&gt; 的事件处理程序捕获。同样,&lt;img&gt; 将从 DOM 中删除,使其无法触发 mouseleave 事件。
【解决方案2】:

您正在替换整个元素,并且新元素没有绑定事件处理程序,并且由于它与您最初绑定的元素不同,因此无法与悬停功能一起使用,请尝试:

$('mySelector').hover(function(){
        $('img', this).prop('src', 'images/myImage2.png');
    },
    function(){
        $('img', this).prop('src', 'images/myImage1.png');
    }
);

或者,如果这不是一个选项,请使用 on() 委托事件

【讨论】:

  • 他替换的是被悬停的元素的 content,而不是元素本身,所以我认为这不是问题。
  • 正如@AnthonyGrist 所说,这不是问题 - 每次我将鼠标悬停在鼠标悬停时都会触发多次(使用萤火虫观察)。
  • 虽然你的答案是错误的(事件处理程序没有丢失或被替换),但你的解决方案确实fix the problem
【解决方案3】:

我同意 PPvG,他在his answer 中声明:

这个问题的原因是触发 mouseenter 事件的元素(即节点)从 DOM 中删除。该事件将 DOM 冒泡到 mySelector,在那里它被捕获和处理,但它是事件的源。因此,mouseleave 事件不是由 new 触发的(鼠标从一开始就没有进入它)是有道理的。

因此,作为解决方案,您可以使用.attr('src','full_url_here')。 adeneo 在their answer 中建议以下代码:

$('#myImg').hover(function()
    {
        $(this).attr("src","http://cdn1.iconfinder.com/data/icons/dellios_system_icons/png_128/css-grey.png");
    },
    function(){
        $(this).attr("src","http://cdn1.iconfinder.com/data/icons/dellios_system_icons/png_128/css.png");
    }
);

附加的 HTML 代码:

<div id="mySelector">
    <img id="myImg" src="http://cdn1.iconfinder.com/data/icons/dellios_system_icons/png_128/css.png" />
</div>

最后是一个演示:http://jsbin.com/elofoc/7/edit#preview

【讨论】:

  • 这是一个正确的选择器。这就是它上面的 mouseover 事件起作用的原因。
  • mySlector是元素的id还是元素的类?最好提供具有mySelector 的HTML。所以我们可以更好地分析它。
  • 您是否只是从其他两个答案中复制了正确的位? =/
  • @PPvG - 我编辑了答案以使归属更加清晰。可以引用其他答案以获得更好的整体答案,但您需要显示您从哪里获取信息。我认为现在这在应得的地方给予了适当的信任。
猜你喜欢
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多