分享有关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 相关文章推荐
jquery $.ajax入门应用二
Nov 19 Javascript
javascript 数组排序函数
Aug 20 Javascript
JS判断是否为数字,是否为整数,是否为浮点数的代码
Apr 24 Javascript
纯css+js写的一个简单的tab标签页带样式
Jan 28 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
Sep 04 Javascript
JavaScript将取代AppleScript?
Sep 18 Javascript
BootStrap响应式导航条实例介绍
May 06 Javascript
javascript中Date对象应用之简易日历实现
Jul 12 Javascript
jQuery图片轮播(二)利用构造函数和原型创建对象以实现继承
Dec 06 Javascript
Vue路由切换时的左滑和右滑效果示例
May 29 Javascript
深入解析ES6中的promise
Nov 08 Javascript
JavaScript实现移动小精灵的案例代码
Dec 12 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
php+ajax做仿百度搜索下拉自动提示框(有实例)
2012/08/21 PHP
php循环创建目录示例分享(php创建多级目录)
2014/03/04 PHP
php上传文件常见问题总结
2015/02/03 PHP
最新最全PHP生成制作验证码代码详解(推荐)
2016/06/12 PHP
阿里对象存储OSS在laravel框架中的使用方法
2019/10/13 PHP
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
jquery+php实现滚动的数字特效
2015/11/29 Javascript
javascript绘制漂亮的心型线效果完整实例
2016/02/02 Javascript
require.js+vue开发微信上传图片组件
2016/10/27 Javascript
jQuery基于ajax操作json数据简单示例
2017/01/05 Javascript
javaScript+turn.js实现图书翻页效果实例代码
2017/02/16 Javascript
详解Vue中一种简易路由传参办法
2017/09/15 Javascript
微信小程序使用form表单获取输入框数据的实例代码
2018/05/17 Javascript
详解js访问对象的属性和方法
2018/10/25 Javascript
vue-cli3 DllPlugin 提取公用库的方法
2019/04/24 Javascript
vue项目打包后上传至GitHub并实现github-pages的预览
2019/05/06 Javascript
layer.open的自适应及居中及子页面标题的修改方法
2019/09/05 Javascript
[46:03]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
一个基于flask的web应用诞生 组织结构调整(7)
2017/04/11 Python
Python将多个excel文件合并为一个文件
2018/01/03 Python
对PyQt5的输入对话框使用(QInputDialog)详解
2019/06/25 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
python celery分布式任务队列的使用详解
2019/07/08 Python
django 2.2和mysql使用的常见问题
2019/07/18 Python
python基于K-means聚类算法的图像分割
2019/10/30 Python
详解Python3 定义一个跨越多行的字符串的多种方法
2020/09/06 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
2021/01/06 Python
The North Face北面美国官网:美国著名户外品牌
2018/09/15 全球购物
斯洛伐克最大的婴儿食品和用品网上商店:Feedo.sk
2020/12/21 全球购物
告诉你怎样写创业计划书
2014/01/27 职场文书
教师敬业奉献模范事迹材料
2014/05/18 职场文书
奖励通知
2015/04/22 职场文书
关爱留守儿童捐款倡议书
2015/04/27 职场文书
2015年度高中教师工作总结
2015/05/26 职场文书
2016年党建工作简报
2015/11/26 职场文书
Logback 使用TurboFilter实现日志级别等内容的动态修改操作
2021/08/30 Java/Android