1

我正在尝试在列表元素上创建一个简单的悬停效果。但是,当鼠标悬停在列表项上时,显示的元素之间存在小的间隙。这会强制mouseleave触发事件,这是不需要的。

这是小提琴演示。将鼠标悬停在列表项上后尝试转到小框。

HTML:

<ul>
    <li>test <div class="block">Block</div></li>
    <li>test2 <div class="block">Block descriptions</div></li>
</ul>​

CSS:

ul { width: 50px; }
ul li { width: 50px; height: 50px; background: #c00; margin: 0 0 10px 0; }
li .block { 
    position: absolute; 
    margin: 0 0 0 70px;
    background: #ddd;
    display: none;
}

JavaScript:

$("ul li").hover(function() {
    $(this).children(".block").stop().fadeIn();
}, function() {
    $(this).children(".block").stop().fadeOut();
});​

如何防止这种影响?

4

4 回答 4

1

试试这个演示

$('ul li').on("mouseenter mouseleave",function( e ){
   var $this = $(this);
   if (e.type == 'mouseenter') {
       clearTimeout( $this.data('timeout') );
       $this.find('.block').stop().fadeTo(400,1);
   }else{
       $this.data( 'timeout', setTimeout(function(){
           $this.find('.block').stop().fadeTo(200,0, function(){
             $(this).hide(); 
           });
       },200) );
   }
});

它的作用是:data为当前悬停li元素的属性设置一个超时值,该值将像悬停意图一样等待 200 毫秒,以等待元素上的 mouseenter.block保持元素可见。一旦鼠标到达您的块元素,它将重置超时。

于 2012-08-20T09:38:17.387 回答
0

像这样的东西应该工作。可能需要一些调整。

http://jsfiddle.net/G5YfR/

var fn = function(elem) {
    $(elem).children(".block").fadeOut();
};
var timeout;
$("ul li").on("mouseenter", function() {
    var that = this;
    clearTimeout(timeout);
    $(this).children(".block").fadeIn();
}).on("mouseleave", function() {
    var that = this;

    timeout = setTimeout(function() {
        fn(that)
    }, 1000);
});
于 2012-08-20T09:46:08.777 回答
0

您有两个附加了鼠标事件处理程序的元素,并且它们彼此相距一小段距离,因此当鼠标在前往另一个元素的途中离开一个元素时,它会超出两个元素并再次触发事件处理程序等.

您可以将两个元素都放在一个包装元素中,并将事件处理程序附加到该元素

<ul>
    <li><div>test <div class="block">Block</div></div></li>
    <li><div>test2 <div class="block">Block descriptions</div></div></li>
</ul>​​​​​​​​​​​​​​​​​​​

js:

$("ul li").on({
    mouseenter: function() {
        $(".block", this).fadeIn();
    },
    mouseleave: function() {
        $(".block", this).fadeOut();
    }
});​

小提琴

或者您可以尝试猜测移动鼠标所需的时间并使用一点超时来伪造它:

var timer;

$("ul li").on({
    mouseenter: function() {
        clearTimeout(timer);
        $(this).children(".block").fadeIn();
    },
    mouseleave: function() {
        var self = this;
        timer = setTimeout(function() {
            $(self).children(".block").fadeOut();
        }, 400);
    }
});​

小提琴

于 2012-08-20T09:48:16.360 回答
0

mouseleave事件被触发是因为当您将鼠标移到孩子身上时,您确实离开了元素。唯一的解决方案是扩展li元素的宽度。

保持外观不变,我建议将红色框移到自己的元素中,例如:

<ul>
    <li>
        <span class="icon">test</span> 
        <span class="block">Block</span>
    </li>
    <li>
        <span class="icon">test2</span> 
        <span class="block">Block descriptions</span>
    </li>
</ul>​

并将 CSS 更改为:

li span {
    display: inline-block;
    vertical-align: middle;
}

li .icon {
    width: 50px; 
    height: 50px; 
    background: #c00;
}

li .block { 
    margin: 0 0 0 70px;
    background: #ddd;
    display: none;
}

li元素延伸到两个孩子:DEMO请注意,这display: inline-block可能不适用于较旧的 IE 版本。(根据http://caniuse.com/inline-block应该没问题)。

于 2012-08-20T10:18:19.333 回答