这样就很尴尬了,之前我们的效果不是还蛮好的么?我们再回到我们的JS代码中分析结构,觉得最有可能出错的就是starMove函数中,我们发现这段代码的意思有点难理解:
if(json[attr] == icur) { clearInterval(obj.timer); if(fn) { fn(); } }
我们并不知道是不是所有的运动都到达终点时停止所有运动还是当只有一个运动达到终点时立马停止所有运动。但是通过我们前面的操作,可以知道的实际结果为,只有一个运动到达终点值时,所有的运动都停止了(此时还有运动没执行完),我们该如何进行操作呢?
思路:我们可以假定一个参数flag,并且赋值为true,在执行clearInterval(obj.timer);操作前我们先进行判断if(json[attr] != icur) { flag = false;},后面执行之前else里面的语句,再执行如下语句if(flag = true) {clearInterval(obj.timer); if(fn) {fn();}},这样我们就可以得到同时运动的完整代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>链式运动</title> <style type="text/css"> body,ul,li{ margin: 0px; padding: 0px; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> </head> <body> <ul> <li></li> </ul> <script type="text/javascript"> window.onload = function(){ var Li = document.getElementById('li1'); Li.onmouseover = function(){ startMove(Li,{width:202,height:200,opacity:100}); }; Li.onmouseout = function(){ startMove(Li,{width:200,height:100,opacity:30}); }; }; function getStyle(obj, attr) { if(obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { //定义标杆 var flag = true; //假设的 clearInterval(obj.timer); obj.timer = setInterval(function() { for(var attr in json) { var icur = 0; if(attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } var speed = (json[attr] - icur) / 10; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if(json[attr] != icur) { flag = false; } if(attr == 'opacity') {//判断是否为opacity obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')'; obj.style.opacity = (icur + speed) / 100; } else { obj.style[attr] = icur + speed + 'px'; } if(flag){ clearInterval(obj.timer); if(fn){ fn(); } } } }, 30) } </script> </body> </html>
这样我们的同时运动的动画效果就实现了。在这里,你有没有觉得很神奇?
在这里我们已经将一个简单的运动插件封装完成了,我们将里面的代码做一些解释,并且将它保存为一个foodoir.animate.js文件,代码如下:
/* * 简单的运动框架 * 作者:foodoir * 此框架仅作参考!!! * * 使用方法见博文 */ function getStyle(obj, attr) { if(obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { clearInterval(obj.timer); //清除定时器,避免重复生成多个定时器 obj.timer = setInterval(function() { var flag = true; //假设刚开始时所有运动都已完成 for(var attr in json) { //遍历json var icur = null; //1.判断类型 if(attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } //2.算速度 var speed = (json[attr] - icur) / 5; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //3.检测停止 if(icur != json[attr]) { flag = false; } if(attr == 'opacity') { obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')'; obj.style.opacity = (icur + speed) / 100; } else { obj.style[attr] = icur + speed + 'px'; } } if(flag) { //当所有运动都完成时,清除定时器 clearInterval(obj.timer); if(fn) { fn(); } } }, 30); }
后面,我们将介绍用自己的框架来实现多种动画效果,并且和jquery中的动画效果进行比较。