分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug


Posted in Javascript onJanuary 10, 2016

我写文章的风格就是喜欢在开头讲问题法伤的背景:

因为最近要做个操作选项的呼出,然后就想到了用默认隐藏,鼠标划过的时候显示的方法。

刚开始打算添加一个class="active",直接触发mouseover(或者mouseenter)的时候add,mouseout(或者mouseleave)的时候remove,这个解决方法很简单,也很实用,但是体验上可能不是那么酷炫(好吧,这个词用的,瞬间感觉好low啊),所以就想到了用animate或者slide这些jQuery的动画,然后一开始讲真,这个插件自己写,会碰到些问题,不太好实现(毕竟js掌握的不是很到位),然后听同事讲去找找jquery,导入后直接引用就可以了。

(还好我没养成一碰到要做某个特效,第一反应是网上找插件,说起这个,又想到前几天碰到的关于将table中的表头对界面滚动而固定的那个解决方法了,过几天传上来,讲真,那个方法网上找了一圈没找到合适的解决方法,最后我自己想了个方法,还是蛮有成绩感的,虽然有可能不是最优的解决方案)

回到正题,网上找了一圈,讲真,别人的插件,做的确实很赞,而且各种浏览器下的兼容性也解决了,不过我个人而言,只在两三个页面用到,而且又要导入文件(这个好像不是特别麻烦),又要用别人的,终归没什么成就感。

然后,最后还是自己动手写了,虽然花了点时间,也碰到了一些问题,不过还是不错的,问题也最后解决了,至少对几个jQuery的内置函数又熟悉了一点。

ps:最后补充一句,在我自己找出解决方案后,再次百度了一下,好吧,出来的第一个网页链接,点进去就是我所用的方法。

bug重现:原本想做个动图的,好像太麻烦了,还是上代码吧,知道这个问题的应该不用看动图也知道是个怎么样的问题;不知道这个问题的,可以先把代码拷贝下来试一下。

PS:下面以animate动画为例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>test</title>
<meta charset="utf-8">
<link rel="stylesheet" href="./bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="./font-awesome/css/font-awesome.min.css">
<script src="./bootstrap/js/jquery-1.11/jquery.min.js"></script>
<script src="./bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div style="width:70%;margin:50px auto;height:300px;">
<div id="test" style="width:900px;height:100px;border:1px solid red;overflow:hidden;">
<div class="test" style="margin-left:-6em">
<a>
测试用的文字
<i class="fa fa-arrow-right"></i>
</a>
</div>
</div>
</div>
<script>
$("[data-toggle='tooltip']").tooltip();

$("#test").on("mouseover",function(){
var $this = $(this);
var $thisTest = $this.find("div.test");
$thisTest.css("position","relative");
// $thisTest.stop();
$thisTest.filter(':not(:animated)').animate({marginLeft:"0em"});
})
.on("mouseout",function(){
var $this = $(this);
var $thisTest = $this.find("div.test");
$thisTest.css("position","relative");
// $thisTest.stop();
$thisTest.filter(':not(:animated)').animate({marginLeft:"-6em"});
})
//连续触发动画bug
//不允许动画累积;或是在新的动画开始前,先停止当前正在进行的动画
</script>
</body>
</html>

上面这份代码,stop()这个方法被我注释掉了,是我个人认为最完美的解决方法,没有被注释掉的,是我后来百度了一下后,别人提到的另一种解决方案,但我个人感觉不是特别完美,至于差别我在后面提。

最开始,

$thisTest.filter(':not(:animated)').animate({marginLeft:"0em"});
$thisTest.filter(':not(:animated)').animate({marginLeft:"-6em"});

这两句代码,是没有filter()函数的,也就是最开始碰到这个bug的时候的代码的样子。

这个bug产生原因就是事件在短时间内(上一个动画未播放完),动画累积导致的(估计碰到这个问题的,回过头去看看代码都知道这个原因)。所以,解决的方法,有两个。

【filter】

一个就是用filter过滤,在动画发生前,过滤掉正在进行动画的元素,只让上一个动画已经结束的元素才能触发新的事件。

然后这就带来一个新问题了,当我把鼠标移至对应的内容上,mouseover事件触发,这个时候,在动画还未结束的时候,我再将鼠标移除对应内容区域外,mouseleave事件触发,但是因为上一个动画还未结束,所以即使触发了该事件,但预期的函数并未执行,此时预期中的“mouseleave事件触发,内容隐藏”结果便无法做到了。

当然,如果操作者在mouseover事件触发的动画结束前,鼠标一直停在对应内容上,这个方案并不会有影响。

【stop】

对于stop(),虽然知道这是大家都了解的,还是再搬一遍吧。

//语法结构
$("#div").stop();//停止当前动画,继续下一个动画
$("#div").stop(true);//清除元素的所有动画
$("#div").stop(false, true);//让当前动画直接到达末状态 ,继续下一个动画
$("#div").stop(true, true);//清除元素的所有动画,让当前动画直接到达末状态

这个方案的思路,就是简单的:当我mouseover的时候,触发对应的动画,但是在动画还未结束的时候,我却要mouseleave,同时触发mouseleave对应的动画,这个时候我便需要停止对应元素正在进行的动画。然后,这个bug也就不存在了。

最后,好吧,这篇随笔好像也没啥总结的,其实就是对animate、slide、fade动画函数的熟悉吧,同时再熟悉一下stop有参数无参数的区别(讲真,刚开始没想到用stop,过了一两天后,偶然看到API的时候,看到了stop,才突然有了用stop解决这个bug的设想)。

以上所述是三水点靠木小编给大家分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug,希望对大家今后的工作学习有所帮助。

Javascript 相关文章推荐
JavaScript 工具库 Cloudgamer JavaScript Library v0.1 发布
Oct 29 Javascript
jquery下将选择的checkbox的id组成字符串的方法
Nov 28 Javascript
Jquery动态更改一张位图的src与Attr的使用
Jul 31 Javascript
JS常见问题整理(持续更新)
Aug 06 Javascript
jQuery中:password选择器用法实例
Jan 03 Javascript
JavaScript父子窗体间的调用方法
Mar 31 Javascript
利用JS提交表单的几种方法和验证(必看篇)
Sep 17 Javascript
Vue通过URL传参如何控制全局console.log的开关详解
Dec 07 Javascript
js+SVG实现动态时钟效果
Jul 14 Javascript
vue router 传参获取不到的解决方式
Nov 13 Javascript
JS轮播图的实现方法2
Aug 25 Javascript
小程序实现文字循环滚动动画
Jun 14 Javascript
理解Angular数据双向绑定
Jan 10 #Javascript
JavaScript表单验证实例之验证表单项是否为空
Jan 10 #Javascript
JavaScript电子时钟倒计时第二款
Jan 10 #Javascript
基于javascript实现彩票随机数生成(简单版)
Apr 17 #Javascript
Node.js静态文件服务器改进版
Jan 10 #Javascript
实例讲解javascript注册事件处理函数
Jan 09 #Javascript
详解javascript事件冒泡
Jan 09 #Javascript
You might like
应用开发中涉及到的css和php笔记分享
2011/08/02 PHP
深入HTTP响应状态码速查表的详解
2013/06/07 PHP
从wamp到xampp的升级之路
2015/04/08 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
php实现基于openssl的加密解密方法
2016/09/30 PHP
javascript 动态添加表格行
2006/06/22 Javascript
xml文档转换工具,附图表例子(hta)
2010/11/17 Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
2011/05/28 Javascript
windows8.1+iis8.5下安装node.js开发环境
2014/12/12 Javascript
node.js中的fs.lstatSync方法使用说明
2014/12/16 Javascript
jQuery数组处理函数整理
2016/08/03 Javascript
利用Node.js对文件进行重命名
2017/03/12 Javascript
vue实现2048小游戏功能思路详解
2018/05/09 Javascript
vue+VeeValidate 校验范围实例详解(部分校验,全部校验)
2018/10/19 Javascript
NVM安装nodejs的方法实用步骤
2019/01/16 NodeJs
JS实现简易留言板(节点操作)
2020/03/16 Javascript
JS如何在不同平台实现多语言方式
2020/07/16 Javascript
Python正则表达式完全指南
2017/05/25 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
python使用tensorflow深度学习识别验证码
2018/04/03 Python
Python基于win32ui模块创建弹出式菜单示例
2018/05/09 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
Python I/O与进程的详细讲解
2019/03/08 Python
Python assert语句的简单使用示例
2019/07/28 Python
解决jupyter notebook 出现In[*]的问题
2020/04/13 Python
Django 用户登陆访问限制实例 @login_required
2020/05/13 Python
Django restful framework生成API文档过程详解
2020/11/12 Python
html5 input属性使用示例
2013/06/28 HTML / CSS
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
加拿大在线隐形眼镜和眼镜店:VisionPros
2019/10/06 全球购物
优秀导游先进事迹材料
2014/01/25 职场文书
售后服务承诺书
2014/03/26 职场文书
三严三实对照检查材料范文
2014/09/23 职场文书
2015感人爱情寄语
2015/02/26 职场文书
高中语文教学反思范文
2016/02/16 职场文书
Python实现随机生成迷宫并自动寻路
2021/06/13 Python