我有一个垂直菜单栏,活动菜单项下方有一条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);
});
});
答案 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