问题
在开发中经常有需要鼠标 hover 时对内容隐藏显示的需求,常用的方式是通过 jquery 的 hover 事件,配合 show/hide 进行实现,具体代码如下:
html:
<ul>
<li>
<p> 标题 1 </p>
</li>
<li>
<p> 标题 2 </p>
</li>
<li>
<p> 标题 3 </p>
</li>
</ul>
js:
$(function () {$('ul li').hover(function () {$(this).children().show()
}, function () {$('p').hide()})
})
这样实现起来是没有问题的,但是过于生硬,只是通过 display: block|none
的方式进行隐藏显示,毫无体验可言,所以改进一下,js 如下:
$(function () {$('ul li').hover(function () {$(this).children().show(500) // 增加 speed 500ms
}, function () {$('p').hide(300) // 增加 speed 300ms
})
})
嗯嗯,可以了,显示的时候增加了动画,不再生硬,但是,问题来了,当鼠标快速的移入移出的时候,即使鼠标已经停止运动,但是动画还没有停止,依然会按照鼠标移入移出的次数执行完成才会停止,这略微有点尴尬,需要解决一下。
解决办法
原本想到的是,既然移入移出有时间延迟,那可以加个延时,在移入的时候判断时候在执行,如果已经在执行动画过程,那么就不执行 show,hide 同理,但是失败了。
那么再看看其他的吧,hover 不行,那使用 mouseenter/mouseout 事件呢,然而,效果是一样的。仔细想了下,应该是因为增加了 speed 之后,相当于每次移入移出,都把隐藏 / 显示的动画增加到了动画的队列中,所以当快速的进行时,即使鼠标停止了,但是队列中的事件还没有执行完,所以依然会按照当前的次数继续执行,直到完成为止。
那么既然这样,jq 一定有自己的方式处理吧,要不然不可能就这样大家都忍受着或者都自己去想各种办法解决,果然,又搜了一下,原来 jq 已经提供了 stop
方法。stop
这个方法的用途就是用于停止动画或效果,在它们完成之前。它接受两个参数:stopAll
:规定是否应该清除动画队列。默认是 false,即仅停止活动的动画,允许任何排入队列的动画向后执行;goToEnd
:规定是否立即完成当前动画,默认是 false。默认地,stop() 会清除在被选元素上指定的当前动画。
修改 js 如下:
$(function () {$('ul li').hover(function () {$(this).children().stop(false, true).show(500)
}, function () {$('p').stop(false, true).hide(300)
})
})
嗯嗯,问题解决了,可以愉快的进进出出了。
看来 jq 用的太少了,对 api 也不够熟练啊,以后还是加强一下吧,嘻嘻。