本文,是接着上文[js高手之路]匀速运动与实例实战(侧边栏,淡入淡出)继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大:
1,支持多个物体的运动
2,同时运动
3,顺序运动
这三种运动方式也是jquery中animate函数支持的
一、animate函数中怎么区分变化不同的样式?
上文中,侧边栏效果 用的animate函数 改变的是left值
1 function animate(obj, target, speed) { 2 ????clearInterval(timer); 3 ????timer = setInterval(function () { 4 ????????if (obj.offsetLeft == target) { 5 ????????????clearInterval(timer); 6 ????????} else { 7 ????????????obj.style.left = obj.offsetLeft + speed + ‘px‘; 8 ????????} 9 ????}, 30);10 }
淡入淡出效果 用的animate函数 改变的是透明度
1 ????????????function animate(obj, target, speed) { 2 ????????????????clearInterval(timer); 3 ????????????????var cur = 0; 4 ????????????????timer = setInterval(function () { 5 ????????????????????cur = css( obj, ‘opacity‘) * 100; 6 ????????????????????if( cur == target ){ 7 ???????????????????????clearInterval( timer ); 8 ????????????????????}else { 9 ????????????????????????cur += speed;10 ????????????????????????obj.style.opacity = cur / 100;11 ????????????????????????obj.style.filter = "alpha(opacity:" + cur + ")";12 ????????????????????}13 ????????????????}, 30);14 ????????????}
而我们封装的函数,要变成通用的,首先面临的问题就是 这个函数要同时支持left值和透明度的变化,更通用的做法应该是要支持所有的样式变化,比如轮播功能,他有左右滑动,也有上下滑动。
我们可以在获取样式和改变样式的时候,做一下判断就可以了,判断分2类就能达到目的,因为其他样式( margin, left, top, right, font-size等等 )都是px,而透明度没有px单位
1 function animate(obj, attr, target, speed) { 2 ????clearInterval(timer); 3 ????var cur = 0; 4 ????timer = setInterval(function () { 5 ????????if (attr == ‘opacity‘) { 6 ????????????cur = css(obj, ‘opacity‘) * 100; 7 ????????} else { 8 ????????????cur = parseInt(css(obj, attr)); 9 ????????}10 11 ????????if (cur == target) {12 ????????????clearInterval(timer);13 ????????} else {14 ????????????if (attr == ‘opacity‘) {15 ????????????????obj.style.opacity = ( cur + speed ) / 100;16 ????????????????obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";17 ????????????} else {18 ????????????????obj.style[attr] = cur + speed + "px";19 ????????????}20 ????????}21 ????}, 30);22 }
合并之后的animate相比之前多了一个参数attr, 这个参数就是变化的样式,obj: 变化的对象, target: 样式需要变化到的目标值. speed: 样式每次变化的大小
如:
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 ????<meta charset="UTF-8"> 5 ????<title>合并的运动 - by ghostwu</title> 6 ????<style> 7 ????????img { 8 ????????????border: none; 9 ????????????opacity: 0.3;10 ????????????filter: alpha(opacity:30);11 ????????????position: absolute;12 ????????????left: 200px;13 ????????}14 15 ????????#box {16 ????????????width: 150px;17 ????????????height: 300px;18 ????????????background: red;19 ????????????position: absolute;20 ????????????left: -150px;21 ????????????top: 50px;22 ????????}23 24 ????????#box div {25 ????????????width: 28px;26 ????????????height: 100px;27 ????????????position: absolute;28 ????????????right: -28px;29 ????????????top: 100px;30 ????????????background: green;31 ????????}32 ????</style>33 ????<script>34 ????????window.onload = function () {35 ????????????var oImg = document.getElementById("img"),36 ????????????????oBox = document.getElementById("box"),37 ????????????????timer = null;38 39 ????????????oImg.onmouseover = function () {40 ????????????????animate(this, ‘opacity‘, 100, 10);41 ????????????}42 ????????????oImg.onmouseout = function () {43 ????????????????animate(this, ‘opacity‘, 30, -10);44 ????????????}45 46 ????????????oBox.onmouseover = function () {47 ????????????????animate(this, ‘left‘, 0, 10);48 ????????????}49 50 ????????????oBox.onmouseout = function () {51 ????????????????animate(this, ‘left‘, -150, -10);52 ????????????}53 54 ????????????function animate(obj, attr, target, speed) {55 ????????????????clearInterval(timer);56 ????????????????var cur = 0;57 ????????????????timer = setInterval(function () {58 ????????????????????if (attr == ‘opacity‘) {59 ????????????????????????cur = css(obj, ‘opacity‘) * 100;60 ????????????????????} else {61 ????????????????????????cur = parseInt(css(obj, attr));62 ????????????????????}63 64 ????????????????????if (cur == target) {65 ????????????????????????clearInterval(timer);66 ????????????????????} else {67 ????????????????????????if (attr == ‘opacity‘) {68 ????????????????????????????obj.style.opacity = ( cur + speed ) / 100;69 ????????????????????????????obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";70 ????????????????????????} else {71 ????????????????????????????obj.style[attr] = cur + speed + "px";72 ????????????????????????}73 ????????????????????}74 ????????????????}, 30);75 ????????????}76 77 ????????????function css(obj, attr) {78 ????????????????if (obj.currentStyle) {79 ????????????????????return obj.currentStyle[attr];80 ????????????????} else {81 ????????????????????return getComputedStyle(obj, false)[attr];82 ????????????????}83 ????????????}84 ????????}85 ????</script>86 </head>87 <body>88 <div >89 ????<div>分享到</div>90 </div>91 <img src="./img/h4.jpg" ?/>92 </body>93 </html>
上述就是完整的代码实例,请自行展开,点击run code预览效果
???????
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 ????<meta charset="UTF-8"> 5 ????<title>Document</title> 6 ????<style> 7 ????????img { 8 ????????????border: none; 9 ????????????opacity: 0.3;10 ????????????filter: alpha(opacity:30);11 ????????????position: absolute;12 ????????????left: 200px;13 ????????}14 15 ????????#box {16 ????????????width: 150px;17 ????????????height: 300px;18 ????????????background: red;19 ????????????position: absolute;20 ????????????left: -150px;21 ????????????top: 50px;22 ????????}23 24 ????????#box div {25 ????????????width: 28px;26 ????????????height: 100px;27 ????????????position: absolute;28 ????????????right: -28px;29 ????????????top: 100px;30 ????????????background: green;31 ????????}32 ????</style>33 ????<script>34 ????????window.onload = function () {35 ????????????var oImg = document.getElementById("img"),36 ????????????????oBox = document.getElementById("box");37 38 ????????????oImg.onmouseover = function () {39 ????????????????animate(this, ‘opacity‘, 100, 10);40 ????????????}41 ????????????oImg.onmouseout = function () {42 ????????????????animate(this, ‘opacity‘, 30, -10);43 ????????????}44 45 ????????????oBox.onmouseover = function () {46 ????????????????animate(this, ‘left‘, 0, 10);47 ????????????}48 49 ????????????oBox.onmouseout = function () {50 ????????????????animate(this, ‘left‘, -150, -10);51 ????????????}52 53 ????????????function animate(obj, attr, target, speed) {54 ????????????????clearInterval(obj.timer);55 ????????????????var cur = 0;56 ????????????????obj.timer = setInterval(function () {57 ????????????????????if (attr == ‘opacity‘) {58 ????????????????????????cur = css(obj, ‘opacity‘) * 100;59 ????????????????????} else {60 ????????????????????????cur = parseInt(css(obj, attr));61 ????????????????????}62 63 ????????????????????if (cur == target) {64 ????????????????????????clearInterval(obj.timer);65 ????????????????????} else {66 ????????????????????????if (attr == ‘opacity‘) {67 ????????????????????????????obj.style.opacity = ( cur + speed ) / 100;68 ????????????????????????????obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";69 ????????????????????????} else {70 ????????????????????????????obj.style[attr] = cur + speed + "px";71 ????????????????????????}72 ????????????????????}73 ????????????????}, 30);74 ????????????}75 76 ????????????function css(obj, attr) {77 ????????????????if (obj.currentStyle) {78 ????????????????????return obj.currentStyle[attr];79 ????????????????} else {80 ????????????????????return getComputedStyle(obj, false)[attr];81 ????????????????}82 ????????????}83 ????????}84 ????</script>85 </head>86 <body>87 <div >88 ????<div>分享到</div>89 </div>90 <img src="./img/h4.jpg" ?/>91 </body>92 </html>
至此,我们就完成了多物体运动与不同样式的修改
二、让animate函数支持多个样式同时改变
比如:
oBox.onmouseover = function(){
??????????????? animate( this, { "width" : 500, "height" : 400 }, 10 );
???????????}
oBox是一个div元素,animate各参数的意思:
this: 当前div元素
{width : 500, "height" : 400 } : 把宽度变成500, 高度变成400,这两个样式要在同一时间完成,
10: 样式每次在原来的基础上变化10(如width初始值200--> 210, 220, 230.....)
完整的同时运动变化 代码:
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 ????<meta charset="UTF-8"> 5 ????<title>Document</title> 6 ????<style> 7 ????div { 8 ????????width: 200px; 9 ????????height: 200px;10 ????????background: red;11 ????}12 ????</style>13 ????<script>14 ????????window.onload = function () {15 ????????????var oBox = document.getElementById("box");16 ????????????oBox.onmouseover = function(){17 // ???????????????animate( this, { "width" : 500, "height" : 500 }, 10 );18 ????????????????animate( this, { "width" : 500, "height" : 400 }, 10 );19 ????????????}20 21 ????????????function animate(obj, attr, speed) {22 ????????????????clearInterval(obj.timer);23 ????????????????var cur = 0;24 ????????????????obj.timer = setInterval(function () {25 ????????????????????for ( var key in attr ) {26 ????????????????????????if (key == ‘opacity‘) {27 ????????????????????????????cur = css(obj, ‘opacity‘) * 100;28 ????????????????????????} else {29 ????????????????????????????cur = parseInt(css(obj, key));30 ????????????????????????}31 ????????????????????????var target = attr[key];32 ????????????????????????if (cur == target) {33 ????????????????????????????clearInterval(obj.timer);34 ????????????????????????} else {35 ????????????????????????????if (key == ‘opacity‘) {36 ????????????????????????????????obj.style.opacity = ( cur + speed ) / 100;37 ????????????????????????????????obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";38 ????????????????????????????} else {39 ????????????????????????????????obj.style[key] = cur + speed + "px";40 ????????????????????????????}41 ????????????????????????}42 ????????????????????}43 ????????????????}, 30);44 ????????????}45 46 ????????????function css(obj, attr) {47 ????????????????if (obj.currentStyle) {48 ????????????????????return obj.currentStyle[attr];49 ????????????????} else {50 ????????????????????return getComputedStyle(obj, false)[attr];51 ????????????????}52 ????????????}53 ????????}54 ????</script>55 </head>56 <body>57 ????<div ></div>58 </body>59 </html>
请自行展开这段代码,这段代码能够同时运动,但是有一个问题:
div的初始宽度与高度( width : 200, height : 200)
变化步长一样( 10 )
变化时间一样( 每30毫秒变化一次 )
目标( width: 500, height : 400 )
你能想到什么问题吗?( 两个人在同一起跑线上,速度一样, 时间一样,但是要同时到达不同的目标,一个500, 一个400 )
答案是很明显的,肯定是目标近的( height : 400 )那个先到达,然后把对象上的定时器关了,另一个目标更远的( width: 500 )肯定到达不了
你可以在这句代码下面,输出当前的值和目标值:
输出来的结果是:
从上图可以看出,height已经达到了400px,但是width停在了410px,为什么不是400px ? 因为width = 400的时候, 就是( cur == 500 ) 相当于( 400 == 500 ) 不成立,所以执行了else语句,width = cur + 10 = 400 + 10 = 410,然后height到达400px停止了定时器,所以width停在了410px.
那么我们怎么解决这个问题呢?
其实也好办,就是height = 400的时候 不要把定时器关了,应该等width = 500的时候再关闭定时器,不就在同一时间,完成了同时到达目标的效果吗?
修改后的代码如下:
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 ????<meta charset="UTF-8"> 5 ????<title>Document</title> 6 ????<style> 7 ????div { 8 ????????width: 200px; 9 ????????height: 200px;10 ????????background: red;11 ????}12 ????</style>13 ????<script>14 ????????window.onload = function () {15 ????????????var oBox = document.getElementById("box");16 ????????????oBox.onmouseover = function(){17 ????????????????animate( this, { "width" : 500, "height" : 400 }, 10 );18 ????????????}19 20 ????????????function animate(obj, attr, speed) {21 ????????????????clearInterval(obj.timer);22 ????????????????var cur = 0;23 ????????????????obj.timer = setInterval(function () {24 ????????????????????var bFlag = true;25 ????????????????????for ( var key in attr ) {26 ????????????????????????if (key == ‘opacity‘) {27 ????????????????????????????cur = css(obj, ‘opacity‘) * 100;28 ????????????????????????} else {29 ????????????????????????????cur = parseInt(css(obj, key));30 ????????????????????????}31 ????????????????????????var target = attr[key];32 ????????????????????????if (cur != target) {33 ????????????????????????????bFlag = false;34 ????????????????????????????if (key == ‘opacity‘) {35 ????????????????????????????????obj.style.opacity = ( cur + speed ) / 100;36 ????????????????????????????????obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";37 ????????????????????????????} else {38 ????????????????????????????????obj.style[key] = cur + speed + "px";39 ????????????????????????????}40 ????????????????????????}41 ????????????????????}42 ????????????????????if ( bFlag ) {43 ????????????????????????clearInterval( obj.timer );44 ????????????????????}45 ????????????????}, 30);46 ????????????}47 48 ????????????function css(obj, attr) {49 ????????????????if (obj.currentStyle) {50 ????????????????????return obj.currentStyle[attr];51 ????????????????} else {52 ????????????????????return getComputedStyle(obj, false)[attr];53 ????????????????}54 ????????????}55 ????????}56 ????</script>57 </head>58 <body>59 ????<div ></div>60 </body>61 </html>
声明一个变量,每次变化完一次( width, height )样式 把bFlag = true, 只要在for循环中有一个没有到达目标,bFlag的值都是false,这样就不会关闭定时器。当两个都到达目标,才关闭定时器.
三、顺序运动
如样式变化,按顺序来,不是同时变化, 如:
oBox.onmouseover = function(){
???????????????//回调函数: 把函数当做参数传递给另一个函数
??????????????? animate( this, { ‘width‘ : 500 }, 10, function(){
??????????????????? animate( this, { ‘height‘ : 500 }, 10 );
??????????????? } );
???????????}
当把width变成500px的时候,如果传递了回调函数, 再接着执行回调函数里面的运动
修改后的完整代码:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 ????<meta charset="UTF-8"> 5 ????<title>通用的匀速运动框架 - by ghostwu</title> 6 ????<style> 7 ????????div { 8 ????????????width: 200px; 9 ????????????height: 200px;10 ????????????background: red;11 ????????}12 ????</style>13 ????<script>14 ????????window.onload = function () {15 ????????????var oBox = document.getElementById("box");16 ????????????oBox.onmouseover = function(){17 ????????????????//回调函数: 把函数当做参数传递给另一个函数18 ????????????????animate( this, { ‘width‘ : 500 }, 10, function(){19 ????????????????????animate( this, { ‘height‘ : 500 }, 10 );20 ????????????????} );21 ????????????}22 23 ????????????function animate(obj, attr, speed, fn ) {24 25 ????????????????clearInterval(obj.timer);26 ????????????????var cur = 0;27 ????????????????obj.timer = setInterval(function () {28 ????????????????????var bFlag = true;29 ????????????????????for (var key in attr) {30 ????????????????????????if (key == ‘opacity‘) {31 ????????????????????????????cur = css(obj, ‘opacity‘) * 100;32 ????????????????????????} else {33 ????????????????????????????cur = parseInt(css(obj, key));34 ????????????????????????}35 ????????????????????????var target = attr[key];36 ????????????????????????if (cur != target) {37 ????????????????????????????bFlag = false;38 ????????????????????????????if (key == ‘opacity‘) {39 ????????????????????????????????obj.style.opacity = ( cur + speed ) / 100;40 ????????????????????????????????obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";41 ????????????????????????????} else {42 ????????????????????????????????obj.style[key] = cur + speed + "px";43 ????????????????????????????}44 ????????????????????????}45 ????????????????????}46 47 ????????????????????if (bFlag) {48 ????????????????????????clearInterval(obj.timer);49 ????????????????????????fn && fn.call( obj );50 ????????????????????}51 ????????????????}, 30);52 ????????????}53 54 ????????????function css(obj, attr) {55 ????????????????if (obj.currentStyle) {56 ????????????????????return obj.currentStyle[attr];57 ????????????????} else {58 ????????????????????return getComputedStyle(obj, false)[attr];59 ????????????????}60 ????????????}61 ????????}62 ????</script>63 </head>64 <body>65 <div ></div>66 </body>67 </html>
[js高手之路]打造通用的匀速运动框架
原文地址:http://www.cnblogs.com/ghostwu/p/7670033.html