分享有关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:void(0)的真正含义实例分析
Aug 20 Javascript
Jquery时间验证和转换工具小例子
Jul 01 Javascript
实用的Jquery选项卡TAB示例代码
Aug 28 Javascript
Javascript 多物体运动的实现
Dec 24 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
Aug 27 Javascript
vue实现添加标签demo示例代码
Jan 21 Javascript
使用Node.js搭建静态资源服务详细教程
Aug 02 Javascript
JS+jQuery实现注册信息的验证功能
Sep 26 jQuery
动态加载、移除js/css文件的示例代码
Mar 20 Javascript
基于Vue 2.0 监听文本框内容变化及ref的使用说明介绍
Aug 24 Javascript
浅析vue中的MVVM实现原理
Mar 04 Javascript
详解vue-cli中使用rem,vue自适应
May 06 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
一些星际专用术语解释
2020/03/04 星际争霸
目录,文件操作详谈―PHP
2006/11/25 PHP
php读取mssql的ntext字段返回值为空的解决方法
2014/12/30 PHP
php5.3后静态绑定用法详解
2016/11/11 PHP
php基于SQLite实现的分页功能示例
2017/06/21 PHP
nodejs 后缀名判断限制代码
2011/03/31 NodeJs
基于JQuery的抓取博客园首页RSS的代码
2011/12/01 Javascript
jQuery.position()方法获取不到值的安全替换方法
2015/03/13 Javascript
jQuery超精致图片轮播幻灯片特效代码分享
2015/09/10 Javascript
jQuery遍历DOM元素与节点方法详解
2016/04/14 Javascript
Bootstrap表单布局样式代码
2016/05/31 Javascript
JavaScript实现图片瀑布流和底部刷新
2017/01/02 Javascript
关于express与koa的使用对比详解
2018/01/25 Javascript
使用vue2实现带地区编号和名称的省市县三级联动效果
2018/11/05 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
2018/12/23 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
2019/04/29 Javascript
解决layui弹出层layer的area过大被遮挡的问题
2019/09/21 Javascript
JS轮播图的实现方法2
2020/08/25 Javascript
python求pi的方法
2014/10/08 Python
详解python单例模式与metaclass
2016/01/15 Python
python中while和for的区别总结
2019/06/28 Python
selenium 多窗口切换的实现(windows)
2020/01/18 Python
python3将变量写入SQL语句的实现方式
2020/03/02 Python
美国牙科折扣计划:DentalPlans.com
2019/08/26 全球购物
工商管理本科毕业生求职信范文
2013/10/05 职场文书
中学生运动会入场词
2014/02/12 职场文书
党风廉设责任书
2014/04/16 职场文书
清正廉洁演讲稿
2014/05/22 职场文书
2014大学校园光棍节活动策划书
2014/09/29 职场文书
放弃继承权公证书
2015/01/23 职场文书
八月迷情观后感
2015/06/11 职场文书
2015年治庸问责工作总结
2015/07/27 职场文书
趣味运动会口号
2015/12/24 职场文书
浅谈Python 中的复数问题
2021/05/19 Python
Redis中一个String类型引发的惨案
2021/07/25 Redis
Android开发实现极为简单的QQ登录页面
2022/04/24 Java/Android