【问题标题】:jQuery mouseout always triggeredjQuery mouseout 总是触发
【发布时间】:2013-12-29 11:43:44
【问题描述】:

我有一个垂直菜单栏,活动菜单项下面有一条 1px 的线。当悬停另一个菜单项时,该行将滑到悬停项下方。当鼠标悬停在菜单上时,该行应滑回活动菜单项。问题是,mouseout 事件总是被触发,即使光标只在菜单项上移动。在这种情况下,每次悬停一个项目时,线条会在其下方滑动,当悬停在其旁边的菜单项时,线条会滑动到活动菜单项(因为触发了鼠标悬停)并从活动项滑动到悬停。

<div class="header">
    <ul>
        <li><a href="#">menu1</a></li>    
        <li><a href="#">menu1</a></li>    
        <li class="active"><a href="#">menu1</a></li>    
        <li><a href="#">menu1</a></li>    
        <li><a href="#">menu1</a></li>
    </ul>

    <div class="line"></div>
</div>

CSS

.header { height: 21px; }
ul { list-style-type: none; margin: 0; padding: 0; height: 20px; }
ul li { display: inline-block; float: left; height: 20px; }
ul li a { padding: 0px 15px; line-height: 20px; }
.line { height: 1px; background-color: red; }

JS

$(document).ready(function(){
    // Select active item
    var currentWidth = $(".header ul li.active").css('width');
    var marginLeft = 0;
    $.each($(".header ul li"), function(){
        if ( $(this).hasClass('active') ) return false;
        else marginLeft += parseInt($(this).css('width').replace('px', ''));
    });
    $(".header .line").css({ 'width': currentWidth, 'margin-left': marginLeft + 'px' });

    // Hover item
    $(".header ul li").hover(function() {
        var thisPos = $(".header ul li").index($(this));
        var thisWidth = parseInt($(this).css('width').replace('px', ''));
        marginLeft = 0;
        $.each($(".header ul li"), function(){
          if ( $(this).is($(".header ul li:eq(" + thisPos + ")")) ) return false;
          else marginLeft += parseInt($(this).css('width').replace('px', ''));
        });
        $(".header .line").animate({ 'width': thisWidth, 'margin-left': marginLeft }, 200);
    }, function(){
        // This one works wrong !!!
        var currentWidth = $(".header ul li.active").css('width');
        var marginLeft = 0;
        $.each($(".header ul li"), function(){
          if ( $(this).hasClass('active') ) return false;
          else marginLeft += parseInt($(this).css('width').replace('px', ''));
        });
        $(".header .line").animate({ 'width': currentWidth, 'margin-left': marginLeft }, 200);
    });

});

Fiddle

【问题讨论】:

    标签: jquery menu mouseover


    【解决方案1】:

    使用ul 元素处理mouseleave,而不是li 元素的mouseleave

    // Hover item
    $(".header ul li").mouseenter(function () {
        var thisPos = $(".header ul li").index($(this));
        var thisWidth = parseInt($(this).css('width').replace('px', ''));
        marginLeft = 0;
        $.each($(".header ul li"), function () {
            if ($(this).is($(".header ul li:eq(" + thisPos + ")"))) return false;
            else marginLeft += parseInt($(this).css('width').replace('px', ''));
        });
        $(".header .line").animate({
            'width': thisWidth,
                'margin-left': marginLeft
        }, 200);
    });
    
    $('.header ul').mouseleave(function () {
        // This one works wrong !!!
        var currentWidth = $(".header ul li.active").css('width');
        var marginLeft = 0;
        $.each($(".header ul li"), function () {
            if ($(this).hasClass('active')) return false;
            else marginLeft += parseInt($(this).css('width').replace('px', ''));
        });
        $(".header .line").animate({
            'width': currentWidth,
                'margin-left': marginLeft
        }, 200);
    })
    

    演示:Fiddle


    另一种方法是基于计时器的解决方案,例如

    var $ul = $('.header ul')
    // Hover item
    $ul.find$("li").hover(function () {
        clearTimeout($ul.data('mouseleave'));
    
        var thisPos = $(".header ul li").index($(this));
        var thisWidth = parseInt($(this).css('width').replace('px', ''));
        marginLeft = 0;
        $.each($(".header ul li"), function () {
            if ($(this).is($(".header ul li:eq(" + thisPos + ")"))) return false;
            else marginLeft += parseInt($(this).css('width').replace('px', ''));
        });
        $(".header .line").animate({
            'width': thisWidth,
                'margin-left': marginLeft
        }, 200);
    }, function () {
        var timer = setTimeout(function () {
            var currentWidth = $(".header ul li.active").css('width');
            var marginLeft = 0;
            $.each($(".header ul li"), function () {
                if ($(this).hasClass('active')) return false;
                else marginLeft += parseInt($(this).css('width').replace('px', ''));
            });
            $(".header .line").animate({
                'width': currentWidth,
                    'margin-left': marginLeft
            }, 200);
        }, 100);
        $ul.data('mouseleave', timer)
    });
    

    演示:Fiddle

    【讨论】:

    • 非常感谢!第一个会正常工作。附言。我刚刚听说过 mouseleave 和 mouseenter。
    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多