jQuery的mouseenter事件持续触发问题

3

我有一个鼠标进入/离开函数,当元素被悬停时会交换内容。但是它似乎不仅在鼠标进入时触发,而且会持续触发。我已经创建了一个jsfiddle here,希望更容易理解。


感谢你提醒我关于看似无限循环的问题。 - Luke
1个回答

3
在你的rotate_start()rotate_reset()函数中,你通过以下代码触发了一个hover事件:
jq('.product-image-container',super_prod).attr('hover','true');

根据JQuery文档,hover()方法绑定了mouseentermouseleave事件的处理程序。因为鼠标移动时会触发hover,所以您基本上无意中应用了递归。
一个简单的解决方法是将.attr('hover','true');替换为.data('hover',true); 以下是一个可扩展的解决方案,可以实现您的目标: HTML:
<div class="item">
    <ul>
        <li>
            Main product photo
        </li>
        <li>
            Alternate product photo 1
        </li>
        <li>
            Alternate product photo 2
        </li>
        <li>
            Alternate product photo 3
        </li>
    </ul>
</div>

CSS:

.item {
    width:200px;
    height:200px;
    background-color:#F0F0F0;
    border:1px solid #666;
}
.item ul li {
    display:none;
}

JQuery:

var jq = jQuery.noConflict();
var timers = [];
var interval_seconds = 2;

jq('.item').mouseenter(function() {

    // Scope this
    var _this = jq(this);

    // Self-executing function
    (function cycle() {

        // Recursive setTimeout accommodates for animation time - setInterval wont
        timers['item'] = setTimeout(function() {

            // Grab the currently visible photo, and the next photo
            var _this_li = _this.find('li:visible');
            var _next_li = _this_li.next();

            // If there is no next photo, cycle back to first photo
            if (_next_li.length == 0) {
                _next_li = _this.find('li:first-child');
            }

            // Animate the rotation
            _this_li.fadeOut('slow', function() {
                _next_li.fadeIn('slow', function() {

                    // Recursion
                    cycle();
                });
            });
        }, interval_seconds * 1000);
    })();
});

jq('.item').mouseleave(function() {

    // Stop the recursive setTimeout
    clearTimeout(timers['item']);

    // Scope this
    var _this = jq(this);

    // Grab the first photo in the list
    var _first_li = _this.find('li:first-child');

    // If the first photo in the list is not the currently visible photo, make it so.
    if (_first_li.not(':visible')) {
        _this.find('li:visible').fadeOut('slow', function() {
            _first_li.fadeIn('slow');
        });
    }
});

jq(function() {

    // Show the first photo on load
    jq('.item').find('li:first-child').fadeIn('slow');
});

Demo: http://jsfiddle.net/AlienWebguy/EY8mM/1/


我尝试了这个解决方案,但似乎并没有起作用。我也有点困惑,这是如何调用悬停函数的? - user398314
2
你正在设置“hover”伪属性,这使得对象认为你正在悬停在它上面,从而触发mouseenter事件。然后再次设置hover属性,如此往复。 - Milimetric
不,你会无意中做同样的事情。你在这里进行图像交换的最终目标是什么? - AlienWebguy
嗯,好的,请给我一分钟时间,我会为您编写更好的代码。 - AlienWebguy
谢谢,伙计,这正是我在寻找的。我还有点困惑为什么它不起作用。悬停属性问题很有道理,但我不确定为什么当我切换到.data()方法时它仍然无法工作。我打算使用你的解决方案,因为它更适合,但我仍然好奇为什么hover()也被调用了。不过还是非常感谢你的帮助! - user398314
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接