网站首页 > 基础教程 正文
前面我们已经掌握了很多运动相关的知识,也构造出了自己的运动框架,当然,它离真正的完成版运动框架还有很远的距离。
链式运动框架
在我们讲解链式运动框架时,我们需要讲解一下什么是回调函数。在我们之前的一个运动函数startMove中,如果我们再添加一个参数,而且该参数是一个函数,我们希望在运动结束后调用这个函数——这就是所谓的回调函数。
function startMove(obj, attr, iTarget, fnEnd){ clearInterval(obj.timer); obj.timer=setInterval(function (){ var cur=0; if(attr=='opacity') { cur=Math.round(parseFloat(getStyle(obj, attr))*100); } else { cur=parseInt(getStyle(obj, attr)); } var speed=(iTarget-cur)/6; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(cur==iTarget) { clearInterval(obj.timer); if(fnEnd)fnEnd(); } else { if(attr=='opacity') { obj.style.filter='alpha(opacity:'+(cur+speed)+')'; obj.style.opacity=(cur+speed)/100; } else { obj.style[attr]=cur+speed+'px'; } } }, 30);};
在clearInterval之后,我们调用这个函数(当然这里需要判断一下函数是否被传入)。
<!DOCTYPE HTML><html> <head> <meta charset="utf-8"> <title>无标题文档</title> <style> #div1 {width:100px; height:100px; background:red; filter:alpha(opacity:30); opacity:0.3;} </style> <script src="move.js"></script> <script> window.onload=function () { var oDiv=document.getElementById('div1'); oDiv.onmouseover=function () { startMove(oDiv, 'width', 300, function (){ startMove(oDiv, 'height', 300, function (){ startMove(oDiv, 'opacity', 100); }); }); }; oDiv.onmouseout=function () { startMove(oDiv, 'opacity', 30, function (){ startMove(oDiv, 'height', 100, function (){ startMove(oDiv, 'width', 100); }); }); }; }; </script> </head> <body> <div id="div1"></div> </body></html>
效果如下:
可以看到,我们通过回调函数的嵌套实现了一个比较炫酷的伸缩展开效果——这就是一个简单的链式运动框架。
完美运动框架
到目前为止,我们学习的运动框架依然是有问题存在的:
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> <style> #div1 {width:100px; height:100px; background:red;} </style> <script src="move.js"></script> <script> window.onload=function () { var oBtn=document.getElementById('btn1'); var oDiv=document.getElementById('div1'); oBtn.onclick=function () { startMove(oDiv, 'width', 300); startMove(oDiv, 'height', 300); }; }; </script> </head> <body> <input id="btn1" type="button" value="运动" /> <div id="div1"></div> </body></html>
效果如下:
可以看到,我们试图让div的宽和高同时变化,但结果而言只有高度发生了变化,原因在于两次调用函数的定时器产生了干扰,因此只有后一个startmove函数生效了。那么,我们现在的运动框架无法使好几个属性同时发生变化,应该怎么解决它呢?答案是通过json,json有一个重要用法是循环——使用for in方法进行。我们之前传入属性和属性值是通过两个参数进行的,现在我们直接传入一个json,将属性和属性值分别作为键名和键值传入,这样我们就可以同时传入好几组值了。
function startMove(obj, json, fnEnd){ clearInterval(obj.timer); obj.timer=setInterval(function (){ var bStop=true; //假设:所有值都已经到了 for(var attr in json) { var cur=0; if(attr=='opacity') { cur=Math.round(parseFloat(getStyle(obj, attr))*100); } else { cur=parseInt(getStyle(obj, attr)); } var speed=(json[attr]-cur)/6; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(cur!=json[attr]) bStop=false; if(attr=='opacity') { obj.style.filter='alpha(opacity:'+(cur+speed)+')'; obj.style.opacity=(cur+speed)/100; } else { obj.style[attr]=cur+speed+'px'; } } if(bStop) { clearInterval(obj.timer); if(fnEnd)fnEnd(); } }, 30);}
通过json键值对和for in循环,我们就可以同时改变一个元素的好几个属性了。这里注意一点,原本的运动框架当属性值等于目标值时,运动就会停下来,但同时运动的时候几个运动结束的时间并不是一样的——我们应该等所有运动都结束之后再关闭定时器,因此我们建立了一个bStop变量来判断是否所有运动都到达了终点。
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> <style> #div1 {width:100px; height:100px; background:red; filter:alpha(opacity:30); opacity:0.3;} </style> <script src="move2.js"></script> <script> window.onload=function () { var oBtn=document.getElementById('btn1'); var oDiv=document.getElementById('div1'); oBtn.onclick=function () { startMove(oDiv, {width:101, height: 300, opacity: 100}, function (){ alert('a'); }); }; }; </script> </head> <body> <input id="btn1" type="button" value="运动" /> <div id="div1"></div> </body></html>
效果如下:
这样,这个框架既可以同时改变元素的不同属性值(通过json实现),也可以分阶段进行属性值改变(通过回调函数实现),就形成了一个比较完美的运动框架,在css2范围内,这个运动框架已经足够使用了。
到这里我们的运动框架基本就已经讲解结束了,这里为大家总结一下我们编写过的运动框架:
startMove(iTarget) 运动框架
startMove(obj, iTarget) 多物体
startMove(obj, attr, iTarget) 任意值
startMove(obj, attr, iTarget, fn) 链式运动
startMove(obj, json) 多值运动
startMove(obj, json, fn) 完美运动框架
我是石川(Blue),如果你觉得我的文章还不错,请多帮我推荐给你的朋友,多谢了。
作者简介:前阿里巴巴高级技术经理,现开课吧技术学院院长。精通C/C++、Java、Python、前端开发等多种开发技术,曾参与淘宝网的早期建设和优化,拥有丰富的企业级系统开发经验,对HTML5移动端互联网技术及生态体系有深厚的造诣。
了解更多前端知识,可以关注文章的评论。
猜你喜欢
- 2024-11-05 JavaScript Math(算数)对象 js math.pi
- 2024-11-05 JS排序算法:冒泡、选择、插入、归并、快速、希尔、堆、计数
- 2024-11-05 javascript+css3催眠水纹动画特效
- 2024-11-05 js洗牌函数 洗牌java代码
- 2024-11-05 「译」 iOS 7 之 HTML5 综合测评:亮点、缺点和槽点
- 2024-11-05 前端必读:如何在 JavaScript 中使用SpreadJS导入和导出 Excel 文件
- 2024-11-05 嵌套地狱_解决嵌套业务逻辑_使用Js的对象_避免数组嵌套
- 2024-11-05 JavaScript排序,不只是冒泡 javascript sort排序
- 2024-11-05 web前端网页开发中常用js方法封装
- 2024-11-05 深入理解JavaScript中 fn() 和 return fn() 的区别
- 最近发表
- 标签列表
-
- jsp (69)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- tail-f (79)
- queryselectorall (63)
- location.search (79)
- bootstrap教程 (74)
- 单例 (62)
- linuxgzip (68)
- 字符串连接 (73)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)