Javascript动画效果(2)


Posted in Javascript onOctober 11, 2016

在前面的文章中讲了简单的Javascript动画效果,这篇文章主要介绍我在改变之前代码时发现的一些问题及解决方法。

在前面的多物体宽度变化的例子中,我们给其增加代码:border: 4px solid #000;我们发现,鼠标移出后,宽度不是200px了,那么究竟是如何产生这种情况的呢?下面我们通过一个新的例子来分析

html代码:
<div id="div1">hello</div>
css代码:
body,div{ margin: 0px; padding: 0px; }
div{ width: 200px; height: 200px; background: red; border: 1px solid #000;}
Javascript代码:

window.onload = function(){
  startMove();    
}
function startMove(){
  setInterval(function(){
    var oDiv = document.getElementById('div1');
    oDiv.style.width = oDiv.offsetWidth-1+'px';
  },30)
}

/*此时的效果为宽度不断增加
 * 加上border: 2px solid #000;之后,不断增大
 * 原因:当前的宽为202,减一后为201,大于200
 * 改变:oDiv.offsetWidth-2
 * 结果:宽永远为200px
 * 改变:字行内样式中加宽为200px<div id="div1" style="width: 200px;"></div>
 * 结果:改变border的值,可以得到宽度减小的效果
 * 思考:使用getStyle函数
 */

 在这里,我们感觉是offsetWidth上存在问题,我们引入getStyle函数(其中的判断分别为兼容ie和firefox),

function getStyle(obj,attr){
  if(obj.currentStyle){//ie
  return obj.currentStyle[attr];
}
  else{//firefox
    return getComputedStyle(obj,false)[attr];
  }
}

然后我们对oDiv.style.width = oDiv.offsetWidth-1+'px';代码进行修改,代码如下:

oDiv.style.width = parseInt(getStyle(oDiv,'width'))-1+'px'; 

在这里,得到的就是不断减小的效果。我们继续对代码进行修改

css中:
div{ font-size: 12px;color: #fff;}
Javascript中:
oDiv.style.fontSize = parseInt(getStyle(oDiv,'fontSize'))+1+'px';
 此时的效果为宽度不断减小,字体不断增大。(前面主要是学习getStyle的用法)

在这里,我们再回到多物体动画上,我们将之前代码中的的obj.offsetWidth改为parseInt(getStyle(obj,'width')),在这里我们通过图片看一下他们间的不同:

Javascript动画效果(2)

 我们可以发现,parseInt(getStyle(obj,'width'))出现了多次,我们可以将将parseInt(getStyle(obj,'width'))赋值给变量icur,这时我们得到的效果就比较好了,此时的代码如下:

<!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;
      }
    </style>
    <script type="text/javascript">
      window.onload = function(){
        var aLi = document.getElementsByTagName('li');
        for(var i = 0; i< aLi.length; i++){
          aLi[i].timer = null;
          aLi[i].onmouseover = function(){
            startMove(this,400);
          }
          aLi[i].onmouseout = function(){
            startMove(this,200);
          }
        } 
      }
      function startMove(obj,iTarget){
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
          var icur = parseInt(getStyle(obj,'width'));
          //将parseInt(getStyle(obj,'width'))赋值给变量icur
          var speed = (iTarget - icur)/10;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(iTarget == icur){
            clearInterval(obj.timer);
          }
          else{
            //obj.style.width = icur+speed+'px';
            obj.style['width'] = icur+speed+'px';
          }
        },30)
      }
      function getStyle(obj,attr){
        if(obj.currentStyle){
          return obj.currentStyle[attr];
        }
        else
        {
          return getComputedStyle(obj,false)[attr];
        }
      }
    </script>
  </head>
  <body>
    <ul>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </body>
</html>

到这里,单一动画效果实现了,如果我们想要第一个li改变宽度,第二个li改变高度,这里我们应该怎样呢?

思路:在li里面加入id,分情况实现,代码:<li id="li1"></li> <li id="li2"></li>

实现:

window.onload = function(){
  var Li1 = document.getElementById('li1');
  var Li2 = document.getElementById('li2');
  Li1.onmouseover = function(){
    startMove(this,400);
  }
  Li1.onmouseout = function(){
    startMove(this,100)
  }
  Li2.onmouseover = function(){
    startMove1(this,400);
  }
  Li2.onmouseout = function(){
    startMove1(this,200)
  }
}
       
function startMove(obj,iTarget){
  clearInterval(obj.timer);
  obj.timer = setInterval(function(){
    var icur = parseInt(getStyle(obj,'height'));
    var speed = (iTarget - icur)/10;
    speed = speed>0?Math.ceil(speed):Math.floor(speed);
    if(iTarget == icur){
      clearInterval(obj.timer);
    }
    else{
      obj.style['height'] = icur+speed+'px';
    }
  },30)
}
 
function startMove1(obj,iTarget){
  clearInterval(obj.timer);
  obj.timer = setInterval(function(){
    var icur = parseInt(getStyle(obj,'width'));
    var speed = (iTarget - icur)/10;
    speed = speed>0?Math.ceil(speed):Math.floor(speed);
    if(iTarget == icur){
      clearInterval(obj.timer);
    }
    else{
      obj.style['width'] = icur+speed+'px';
    }
  },30)
}
 
function getStyle(obj,attr){
  if(obj.currentStyle){//ie
    return obj.currentStyle[attr];
  }
  else
  {
    return getComputedStyle(obj,false)[attr];
  }
}
 

 这里的效果是:鼠标在第一个时,改变高度;在第二个时,改变宽度。并且我们发现前面的代码中有很多重复的,我们依然根据以前的方法,将不同的部分取出来,用参数的方法传进去同样达到我们想要的效果,(这里不同的是width和height,我们用一个参数attr来传进去),代码如下:

window.onload = function(){
  var Li1 = document.getElementById('li1');
  var Li2 = document.getElementById('li2');
  Li1.onmouseover = function(){
    startMove(this,'height',400);
  }
  Li1.onmouseout = function(){
    startMove(this,'height',100)
  }
  Li2.onmouseover = function(){
    startMove(this,'width',400);
  }
  Li2.onmouseout = function(){
    startMove(this,'width',200)
  }
}
       
function startMove(obj,attr,iTarget){
  clearInterval(obj.timer);
  obj.timer = setInterval(function(){
    var icur = parseInt(getStyle(obj,attr));
    var speed = (iTarget - icur)/10;
    speed = speed>0?Math.ceil(speed):Math.floor(speed);
    if(iTarget == icur){
      clearInterval(obj.timer);
    }
    else{
      obj.style[attr] = icur+speed+'px';
    }
  },30)
}

 在这里,我们试着给透明度也来进行变化,

css中:
ul li{ filter:alpha(opacity:30);opacity:0.3;}

Javascript中:

window.onload = function(){
  var Li1 = document.getElementById('li1');
  var Li2 = document.getElementById('li2');
  Li1.onmouseover = function(){
    startMove(this,'opacity',100);
  }
  Li1.onmouseout = function(){
    startMove(this,'opacity',30)
  }
}

 奇怪的是,居然没有我们想要的结果

原因:假设1:宽度一般为整型,而opacity的值为0-1;假设2:opacity是没有单位的

修改1:增加一个判断,当传入的值为opacity的时候,我们执行parseFloat,代码如下:

var icur = 0;
if(attr == 'opacity'){
  icur = parseFloat(getStyle(obj,attr))*100;
}else{
  icur = parseInt(getStyle(obj,attr));
}

修改2:再增加一个判断

if(iTarget == icur){
  clearInterval(obj.timer);
}
else{
if(attr = 'opacity'){
  obj.style.filter = 'alpha(opacity:'+(icur+speed)+')';
  obj.style.opacity = (icur+speed)/100;
}
else{
obj.style[attr] = icur+speed+'px';
}
}

 修改后我们在浏览器下,仍能发现问题,就是opacity的值比1大了一点点

原因分析:计算机的运算并不是那么准确,会出现误差,

修改:我们在前面增加一个 Math.round,对小数部分进行四舍五入,代码如下

var icur = 0;
if(attr == 'opacity'){
  icur = Math.round(parseFloat(getStyle(obj,attr))*100);
}else{
  icur = parseInt(getStyle(obj,attr));
}

 这样,我们的效果就基本完成了,全部代码如下:

<!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>
    <script type="text/javascript">
      window.onload = function(){
        var Li1 = document.getElementById('li1');
        var Li2 = document.getElementById('li2');
        Li1.onmouseover = function(){
          startMove(this,'opacity',100);
        }
        Li1.onmouseout = function(){
          startMove(this,'opacity',30)
        }
      }
     
      function startMove(obj,attr,iTarget){
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
          var icur = 0;
          if(attr == 'opacity'){
            icur = Math.round(parseFloat(getStyle(obj,attr))*100);
          }else{
            icur = parseInt(getStyle(obj,attr));
          }
          var speed = (iTarget - icur)/10;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(iTarget == icur){
            clearInterval(obj.timer);
          }
          else{
            if(attr = 'opacity'){
              obj.style.filter = 'alpha(opacity:'+(icur+speed)+')';
              obj.style.opacity = (icur+speed)/100;
            }
            else{
              obj.style[attr] = icur+speed+'px';
            }
          }
        },30)
      }   
       
      function getStyle(obj,attr){
        if(obj.currentStyle){
          return obj.currentStyle[attr];
        }
        else
        {
          return getComputedStyle(obj,false)[attr];
        }
      }
    </script>
  </head>
  <body>
    <ul>
      <li id="li1"></li>
    </ul>
  </body>
</html>

 这样,我们就可以对我们的运动进行任意值的变化了。

其实,在不是不觉间,就已经将一个简单的动画进行了封装,得到一个简单的Javascript动画库了。后面,我们将继续对我们Javascript库进行补充。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件
Sep 12 Javascript
javascript中IE浏览器不支持NEW DATE()带参数的解决方法
Mar 01 Javascript
表单的焦点顺序tabindex和对应enter键提交
Jan 04 Javascript
jquery validation验证身份证号,护照,电话号码,email(实例代码)
Nov 06 Javascript
jquery取子节点及当前节点属性值的方法
Sep 09 Javascript
完美解决IE9浏览器出现的对象未定义问题
Sep 29 Javascript
微信小程序 wxapp内容组件 progress详细介绍
Oct 31 Javascript
JavaScript中最常见的三个面试题解析
Mar 04 Javascript
老生常谈JavaScript面向对象基础与this指向问题
Oct 16 Javascript
JS实现点餐自动选择框(案例分析)
Dec 10 Javascript
webpack+vue-cil 中proxyTable配置接口地址代理操作
Jul 18 Javascript
Openlayers3实现车辆轨迹回放功能
Sep 29 Javascript
Javascript动画效果(1)
Oct 11 #Javascript
原生Javascript和jQuery做轮播图简单例子
Oct 11 #Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
Oct 11 #Javascript
javascript之with的使用(阿里云、淘宝使用代码分析)
Oct 11 #Javascript
Node.js的文件权限及读写flag详解
Oct 11 #Javascript
最原始的jQuery注册验证方式
Oct 11 #Javascript
js正则表达式注册页面表单验证
Oct 11 #Javascript
You might like
php中处理模拟rewrite 效果
2006/12/09 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
2014/06/22 PHP
ucenter通信原理分析
2015/01/09 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
国外大牛IE版本检测!现在IE都到9了,IE检测代码
2012/01/04 Javascript
js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
2012/12/27 Javascript
jQuery渐变发光导航菜单的实例代码
2013/03/27 Javascript
在Linux上用forever实现Node.js项目自启动
2014/07/09 Javascript
JavaScript实现函数返回多个值的方法
2015/06/09 Javascript
JS+CSS实现分类动态选择及移动功能效果代码
2015/10/19 Javascript
理解jquery事件冒泡
2016/01/03 Javascript
JavaScript ES5标准中新增的Array方法
2016/06/28 Javascript
Vue resource中的GET与POST请求的实例代码
2017/07/21 Javascript
Three.js利用性能插件stats实现性能监听的方法
2017/09/25 Javascript
浅谈如何使用 webpack 优化资源
2017/10/20 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
微信小程序调用微信支付接口的实现方法
2019/04/29 Javascript
对layui数据表格动态cols(字段)动态变化详解
2019/10/25 Javascript
vue实现路由监听和参数监听
2019/10/29 Javascript
Python实现邮件的批量发送的示例代码
2018/01/23 Python
使用Python爬了4400条淘宝商品数据,竟发现了这些“潜规则”
2018/03/23 Python
python实现简单五子棋游戏
2019/06/18 Python
基于pytorch的保存和加载模型参数的方法
2019/08/17 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
python 定义类时,实现内部方法的互相调用
2019/12/25 Python
PyCharm汉化安装及永久激活详细教程(靠谱)
2020/01/16 Python
浅谈Python的方法解析顺序(MRO)
2020/03/05 Python
HTML5 LocalStorage 本地存储刷新值还在
2017/03/10 HTML / CSS
入党自我评价优缺点
2014/01/25 职场文书
2014年寒假社会实践活动心得体会
2014/04/07 职场文书
《月亮湾》教学反思
2014/04/14 职场文书
趣味运动会广播稿
2014/09/13 职场文书
2015幼儿园新学期寄语
2015/02/27 职场文书
员工升职自我评价
2019/03/26 职场文书
win11高清晰音频管理器在哪里?win11找不到高清晰音频管理器解决办法
2022/04/08 数码科技