实例引入
制作如图的下拉菜单。
功能:鼠标移入时二级菜单向下展开,移出时二级菜单向上收回。
jQuery代码如下:
$(function() {// 在入口函数绑定鼠标移动事件// 给一级菜单元素li的子元素ul(二级菜单列表)增加下滑/上滑动画$(\".nav>li\").hover(function() {// 绑定鼠标移入事件var $sub = $(this).children(\".sub\");$sub.slideDown(1000);}, function() {//绑定鼠标移出事件var $sub = $(this).children(\".sub\");$sub.slideUp(1000);})})
页面结构如下:
问题: 当鼠标慢速移入移出一级菜单时,动画显示正常;但是,当鼠标快速移入移出多次时会发现:二级菜单的动画速度低于鼠标移动的速度,当鼠标暂停后,二级菜单持续下拉上滑,直到完成之前触发的所有事件。(仿佛是在自嗨)
造成这个现象的原因,正是标题中说到的动画队列。
- 鼠标第一次移入,触发a1(下拉动画);
- a1未执行完,鼠标移出,触发a2(上滑动画)
- 鼠标移入移出多次后,就形成如图所示的动画队列,由于队列先进先出的特点,多个动画只能按照触发时间依次完成。(a1 → a2 → a3 → … )
如此一来,就很影响用户体验。
解决方法:调用stop()
要让页面实时显示当前触发的动画,就必须清除队列中的之前触发的动画。
// 修改鼠标移动事件的代码// 在执行当前动画之前,清除所有正在运行的动画(即清空动画队列)$(\".nav>li\").hover(function() {var $sub = $(this).children(\".sub\");// 清空动画队列$sub.stop();$sub.slideDown(1000);}, function() {var $sub = $(this).children(\".sub\");// 清空动画队列$sub.stop();$sub.slideUp(1000);})
动画队列的应用:链式编程
例:完成弹窗广告的动画效果:广告从右下方滑动进入视口,显示完全后淡出,然后快速淡入。
题目中要求的三个动画(滑动slideDown,淡出fadeOut,淡入fadeIn)是依次完成的,常规编程思路是代码嵌套,后一个动画的代码放入上一个动画的回调函数里。
$(\".ad\").slideDown(1000, function(){$(this).fadeOut(1000, function(){$(this).fadeIn(1000);})})
代码嵌套,可读性差。
解决方法:
//链式编程//为保证动画效果,在slideDown前面加上stop方法$(\".ad\").stop().slideDown(1000).fadeOut(1000).fadeIn(200);