jQuery mouseout总是被触发

时间:2013-12-29 11:43:45

标签: jquery menu mouseover

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

<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

1 个答案:

答案 0 :(得分:0)

代替li元素的mouseleave,处理来自ul元素的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