博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js动画学习(五)
阅读量:4655 次
发布时间:2019-06-09

本文共 3970 字,大约阅读时间需要 13 分钟。

九、多属性同时运动

 

      前面的例子都是每个属性单独运动,如果想要多属性同时运动怎么办?比如,我想要一个div的onmouseover事件中宽和高同时变化。下面这个函数是单独变宽:

window.οnlοad=function(){

            var ob1=document.getElementById('div1');
            ob1.οnmοuseοver=function(){
                startMove(ob1,'width',400);
            }

      有一个想法就是在startMove下面再加一个startMove:

  window.οnlοad=function(){

            var ob1=document.getElementById('div1');
            ob1.οnmοuseοver=function(){
                startMove(ob1,'width',400);

       startMove(ob1,'height',400);

            }
}

      事实证明这种想法是错误的,这么写只有高变了,而宽没变。为什么呢?因为startMove函数的起初就是关闭定时器,当第一个startMove函数刚刚开始执行时,第二个startMove已经开始执行,第二个startMove的关闭定时器功能将第一个startMove的定时器覆盖掉了,所以物体的宽无法变化,变的只有高。那么如何解决?这里需要用到json:

var json={a:12,b:13};

for(var i in json){
    alert(i);
    alert(json[i]);
}

      json里的值是成对出现的,每一对为变量和变量的值。可以用for in循环来获取每一对的变量以及对应的值。上面程序依次弹出a,12,b,13 。

      下面来看一下stareMove框架,发现参数里的“属性”和“目标值”是一对值,也就是说一个startMove只能实现一对值的变化。如何实现多对值的变化?来看看这个样子的startMove :

      startMove(obj,{attr1:target1,attr2:target2},fn),蓝色部分就是json的形式,所以在原来的startMove基础上,将蓝色部分换成json ;将程序中的target换成json[attr](是哪个属性,就是那个属性的目标值)。改变完的startMove函数如下:(第1,4,13,16行做了改动)

1 function startMove(obj,json,fn) {
//元素,改变的样式属性,达到的目标值,回调函数 2 clearInterval(obj.timer); 3 obj.timer=setInterval(function(){ 4 for(var attr in json){ 5 //1.取当前值 6 var icur=0;//icur返回物体样式属性值的大小 7 if (attr=='opacity') {
//如果属性是透明度,透明度的返回值是零点几的小数 8 icur=Math.round(parseFloat(getStyle(obj,attr))*100);//round函数避免透明度值在小数之间来回跳动 9 } else {10 icur=parseInt(getStyle(obj,attr));11 }12 //2.算速度13 var speed=(json[attr]-icur)/8;//分母为比例系数K,可调14 speed=speed>0?Math.ceil(speed):Math.floor(speed);//缓冲速度要取整,不然移动不到终点就停止15 //3.检测运动是否停止16 if (icur==json[attr]) {17 clearInterval(obj.timer);18 if(fn){
//上一个运动停止后判断一下是否还有下一个运动19 fn();20 }21 } else {22 if (attr=='opacity') {23 obj.style.filter='alpha(opacity:'+(icur+speed)+')';//IE浏览器24 obj.style.opacity=(icur+speed)/100;//火狐浏览器25 } else {26 obj.style[attr]=icur+speed+'px';27 }28 }29 }30 },30)31 }

        下面是一个div调用startMove函数达到宽高同时变化的效果:

1 
1 

       可以再加一对透明度,实现宽、高、透明度同时变化:

1 

       

        本框架存在的问题:当我想要把宽变为201,高变为400,透明度变为100时,会出现一个问题:宽确实变成201,但是高和透明度还远远未达到目标值,运动就停止了。原因是17行的关闭定时器,原程序里只要有一个属性值达到目标值,就关闭定时器,并没有对每个属性是否达到目标值都做判断。所以出现了当宽达到了目标值,高和透明度还没有达到目标值的时候定时器就关闭了。解决办法:我们需要判断所有的属性都达到目标值时才关闭定时器。(第2行,第17行以后有改动)

1 function startMove(obj,json,fn) {
//元素,改变的样式属性,达到的目标值,回调函数 2 var flag=true;//定义一个标杆,假设所有运动都达到了目标值 3 clearInterval(obj.timer); 4 obj.timer=setInterval(function(){ 5 for(var attr in json){ 6 //1.取当前值 7 var icur=0;//icur返回物体样式属性值的大小 8 if (attr=='opacity') {
//如果属性是透明度,透明度的返回值是零点几的小数 9 icur=Math.round(parseFloat(getStyle(obj,attr))*100);//round函数避免透明度值在小数之间来回跳动10 } else {11 icur=parseInt(getStyle(obj,attr));12 }13 //2.算速度14 var speed=(json[attr]-icur)/8;//分母为比例系数K,可调15 speed=speed>0?Math.ceil(speed):Math.floor(speed);//缓冲速度要取整,不然移动不到终点就停止16 //3.检测运动是否停止17 if (icur!=json[attr]) {
//如果不是所有的运动都达到目标值18 flag=false;19 }20 if (attr=='opacity') {
//没达到目标值的继续运动21 obj.style.filter='alpha(opacity:'+(icur+speed)+')';//IE浏览器22 obj.style.opacity=(icur+speed)/100;//火狐浏览器23 } else {24 obj.style[attr]=icur+speed+'px';25 }26 27 if(flag){
//如果所有的运动都达到了目标值,再关闭定时器,然后看看有没有链式运动28 clearInterval(obj.timer);29 if(fn){30 fn();31 }32 }33 }34 35 },30)36 }

        现在这个改动完的框架就是完美框架了,一些网站上常用的小动画就可以用这个框架实现。

转载于:https://www.cnblogs.com/csxiaoyu/p/5204090.html

你可能感兴趣的文章
extjs4.1:两个combobox的联动
查看>>
百度地图瓦片工具:定义坐标
查看>>
jmeter控制器--交替控制器
查看>>
hdu 5365 Run
查看>>
SVN 常用命令一览表
查看>>
css中可继承和不可继承属性
查看>>
980. Unique Paths III
查看>>
git 博客搭建
查看>>
7-13 求链式线性表的倒数第K项(20 分)
查看>>
快速排序
查看>>
一口一口吃掉Struts(十)——异常自动处理机制
查看>>
并查集,以及可拆分并查集
查看>>
六个优雅的 Linux 命令行技巧
查看>>
MyBatis源码分析
查看>>
ArrayList构造函数
查看>>
C8051F_CAN
查看>>
初写Python
查看>>
新手理解HTML、CSS、javascript之间的关系
查看>>
jap _spring _maven
查看>>
IIS principle
查看>>