JS运动特效之任意值添加运动的方法分析


Posted in Javascript onJanuary 24, 2018

本文实例讲述了JS运动特效之任意值添加运动的方法。分享给大家供大家参考,具体如下:

回顾一下上个例子JS实现多物体运动的方法:

JS运动特效之任意值添加运动的方法分析

<script>
    window.onload = function(){
      var liTags = document.getElementsByTagName('li');
      for(var i=0;i<liTags.length;i++){
         liTags[i].timer = null;// 给每个li都添加一个timer
         liTags[i].onmouseover = function () {
          startMove(this,400);
         }
         liTags[i].onmouseout = function () {
          startMove(this,200);
         }
      }
    }
    function getStyle(obj,attr){
      return getComputedStyle ? getComputedStyle(obj,false)[attr] : obj.currentStyle[attr];
    }
    function startMove(obj,iTarget) {
      clearInterval(obj.timer);
      obj.timer = setInterval(function () {
        var objWidth = parseInt(getStyle(obj,'width'));//因为是通过[]调用属性,所以width必须加单引号
        // var iSpeed = (iTarget -obj.offsetWidth)/10;
        // 因为objWidth存放的就是当前对象的宽,所以直接写objWidth而不是obj.objWidth
        var iSpeed = (iTarget -objWidth)/10;
          iSpeed = iSpeed>0 ?Math.ceil(iSpeed):Math.floor(iSpeed);
        if(objWidth == iTarget){
          clearInterval(obj.timer);
        }else{
          obj.style.width = objWidth+iSpeed+'px';
        }
      },30);
    }
</script>

如果此时需求有变化,让第2个li鼠标移入,高度变化,第三个li鼠标依然边框,第四个li鼠标移入背景变化。一种办法就是复制几分startMove函数,分别把之前width变化改成height,borderWidht,和opacity透明度变化;但是这样显然浪费,可以把他们合并成一个函数,把变化的属性作为参数传进去就好了.

1. function startMove(obj,attr,iTarget) 函数里新增attr参数
2. 调用参数的方式:由obj.style.属性名 变成 obj.style[属性名]
3. 需要分别为每个li添加事件

<script>
    window.onload = function(){
      var liTags = document.getElementsByTagName('li');
      for(var i=0;i<liTags.length;i++){
        liTags[i].timer = null;// 给每个li都添加一个timer
        liTags[0].onmouseover = function () {
          startMove(this,'width',400);
        }
        liTags[0].onmouseout = function () {
          startMove(this,'width',200);
        }
        liTags[1].onmouseover = function () {
          startMove(this,'height',100);
        }
        liTags[1].onmouseout = function () {
          startMove(this,'height',50);
        }
        liTags[2].onmouseover = function () {
          startMove(this,'borderWidth',10);
        }
        liTags[2].onmouseout = function () {
          startMove(this,'borderWidth',2);
        }
        liTags[3].onmouseover = function () {
          startMove(this,'padding',10);
        }
        liTags[3].onmouseout = function () {
          startMove(this,'padding',0);
        }
      }
    }
    function getStyle(obj,attr){
      return getComputedStyle ? getComputedStyle(obj,false)[attr] : obj.currentStyle[attr];
    }
    function startMove(obj,attr,iTarget) {//attr:把变化的属性最为参数传入
      clearInterval(obj.timer);
      obj.timer = setInterval(function () {
        var objAttr = parseInt(getStyle(obj,attr));
        var iSpeed = (iTarget -objAttr)/10;
        iSpeed = iSpeed>0 ?Math.ceil(iSpeed):Math.floor(iSpeed);
        if(objAttr == iTarget){
          clearInterval(obj.timer);
        }else{
          //obj.style.width = objWidth+iSpeed+'px';
          obj.style[attr] = objAttr+iSpeed+'px';// 需要又.属性名的形式改成[]
        }
      },30);
    }
</script>

运行一下发现,改变宽,高,border都妥妥的,但是最后一个改变“透明度”没反应,是什么问题那??

首先opacity的值0.3一个小数,parseInt(getStyle(obj,attr)之后便变成0,还有最大的一个问题就是最后属性值设置的时候:obj.style[attr] =  objAttr+iSpeed+'px'; 显然opacity并没有px这个单位,所以需要对运动框架做进一步处理

需要判断一下,当接受的参数是“透明度”的时候,需要单独处理一下,把上面出问题的两个地方做一下处理

var objAttr = 0;
if(attr == "opacity"){
   // 由于计算机对 小数的处理有问题,这里用Math.round处理一下
   // objAttr = parseFloat(getStyle(obj,attr)*100);
  //objAttr = parseInt(parseFloat(getStyle(obj,attr))*100);
  objAttr = Math.round(parseFloat(getStyle(obj,attr))*100);
}else{
   objAttr = parseInt(getStyle(obj,attr));
}

如果不做处理直接 objAttr = parseFloat(getStyle(obj,attr)*100); 由于计算机不能很精确的处理小数,会导致一些问题

JS运动特效之任意值添加运动的方法分析

用parseInt这种方法:objAttr = parseInt(parseFloat(getStyle(obj,attr))*100); 也可以处理小数,但是经过测试在鼠标移出的时候,与原来状态有一点偏差

JS运动特效之任意值添加运动的方法分析

可以看出,当鼠标移出去的时候,opacity应该回到1,可结果却是0.94 ;所以个人推荐用Math.round四舍五入函数来处理这里的小数问题

JS运动特效之任意值添加运动的方法分析

做一下判断,下面也同样做判断

if(attr == "opacity"){
  obj.style.filter = 'alpha(opacity:'+(objAttr+iSpeed)+')';
  obj.style.opacity = (objAttr+iSpeed)/100;
}else{
  //obj.style.width = objWidth+iSpeed+'px';
  obj.style[attr] = objAttr+iSpeed+'px';// 需要又.属性名的形式改成[]
}

完整代码:

HTML部分

<body>
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
</body>

css部分:

<style>
    ul{list-style: none;}
    ul li{
      margin: 10px;
      width: 200px;height: 50px;
      border: 2px solid #c00;
      background: lightblue;
    }
</style>

js部分

<script>
    window.onload = function(){
      var liTags = document.getElementsByTagName('li');
      for(var i=0;i<liTags.length;i++){
        liTags[i].timer = null;// 给每个li都添加一个timer
        liTags[0].onmouseover = function () {
          startMove(this,'width',400);
        }
        liTags[0].onmouseout = function () {
          startMove(this,'width',200);
        }
        liTags[1].onmouseover = function () {
          startMove(this,'height',100);
        }
        liTags[1].onmouseout = function () {
          startMove(this,'height',50);
        }
        liTags[2].onmouseover = function () {
          startMove(this,'borderWidth',10);
        }
        liTags[2].onmouseout = function () {
          startMove(this,'borderWidth',2);
        }
        liTags[3].onmouseover = function () {
          startMove(this,'opacity',30);
        }
        liTags[3].onmouseout = function () {
          startMove(this,'opacity',100);
        }
      }
    }
    function getStyle(obj,attr){
      return getComputedStyle ? getComputedStyle(obj,false)[attr] : obj.currentStyle[attr];
    }
    function startMove(obj,attr,iTarget) {//attr:把变化的属性最为参数传入
      clearInterval(obj.timer);
      obj.timer = setInterval(function () {
        var objAttr = 0;
        if(attr == "opacity"){
          // 由于计算机对 小数的处理有问题,这里用parseFloat转一下
          objAttr = Math.round(parseFloat(getStyle(obj,attr))*100);
        }else{
           objAttr = parseInt(getStyle(obj,attr));
        }
        var iSpeed = (iTarget -objAttr)/10;
        iSpeed = iSpeed>0 ?Math.ceil(iSpeed):Math.floor(iSpeed);
        if(objAttr == iTarget){
          clearInterval(obj.timer);
        }else{
          if(attr == "opacity"){
            obj.style.filter = 'alpha(opacity:'+(objAttr+iSpeed)+')';
            obj.style.opacity = (objAttr+iSpeed)/100;
          }else{
            //obj.style.width = objWidth+iSpeed+'px';
            obj.style[attr] = objAttr+iSpeed+'px';
          }
        }
      },30);
    }
</script>

最后结果演示:

 JS运动特效之任意值添加运动的方法分析

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jquery 最简单的属性菜单
Oct 08 Javascript
javascript DOM编程实例(智播客学习)
Nov 23 Javascript
jquery实现的V字形显示效果代码
Oct 27 Javascript
jquery自定义表格样式
Nov 23 Javascript
理解JavaScript中worker事件api
Dec 25 Javascript
单击按钮发送验证码,出现倒计时的简单实例
Mar 17 Javascript
详解Webpack+Babel+React开发环境的搭建的方法步骤
Jan 09 Javascript
微信小程序数据存储与取值详解
Jan 30 Javascript
vue将时间戳转换成自定义时间格式的方法
Mar 02 Javascript
在移动端使用vue-router和keep-alive的方法示例
Dec 02 Javascript
JavaScript原型式继承实现方法
Nov 06 Javascript
ES6 Object.assign()的用法及其使用
Jan 18 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
Jan 24 #Javascript
详解node child_process模块学习笔记
Jan 24 #Javascript
浅谈Node.js 子进程与应用场景
Jan 24 #Javascript
除Console.log()外更多的Javascript调试命令
Jan 24 #Javascript
深入理解node.js http模块
Jan 24 #Javascript
微信、QQ、微博、Safari中使用js唤起App
Jan 24 #Javascript
基于node打包可执行文件工具_Pkg使用心得分享
Jan 24 #Javascript
You might like
PHP中for与foreach的区别分析
2011/03/09 PHP
用PHP实现 上一篇、下一篇的代码
2012/09/29 PHP
PHP运行环境配置与开发环境的配置(图文教程)
2013/06/04 PHP
解析php中获取系统信息的方法
2013/06/25 PHP
如何在Ubuntu下启动Apache的Rewrite功能
2013/07/05 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
php控制文件下载速度的方法
2015/03/24 PHP
php上传后台无法收到数据解决方法
2019/10/28 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
2020/05/14 PHP
漂亮的提示信息(带箭头)
2007/03/21 Javascript
jQuery代码优化 事件委托篇
2011/11/01 Javascript
JS实现屏蔽shift,Ctrl,alt等功能键的方法
2015/06/01 Javascript
jQuery禁用键盘后退屏蔽F5刷新及禁用右键单击
2016/01/22 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
利用css+原生js制作简单的钟表
2020/04/07 Javascript
jsTree使用记录实例
2016/12/01 Javascript
jQuery实现Table表格隔行变色及高亮显示当前选择行效果示例
2017/02/14 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
node作为中间服务层如何发送请求(发送请求的实现方法详解)
2018/01/02 Javascript
详解.vue文件中style标签的几个标识符
2018/07/17 Javascript
微信小程序websocket聊天室的实现示例代码
2019/02/12 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
[05:56]第十六期——新进3大C之小兔基
2014/06/24 DOTA
[58:58]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第二场
2018/04/05 DOTA
Python itertools模块详解
2015/05/09 Python
Python3 处理JSON的实例详解
2017/10/29 Python
python中利用h5py模块读取h5文件中的主键方法
2018/06/05 Python
html5 canvas简单封装一个echarts实现不了的饼图
2018/06/12 HTML / CSS
Farfetch美国:奢侈品牌时尚购物平台
2019/05/02 全球购物
大学生入党自我鉴定
2013/10/31 职场文书
网页设计个人找工作求职信
2013/11/28 职场文书
2015年机关党委工作总结
2015/05/23 职场文书
地震捐款简报
2015/07/21 职场文书
《家世》读后感:看家训的力量
2019/12/30 职场文书
Jmerte 分布式压测及分布式压测配置
2022/04/30 Java/Android
Redis实现分布式锁的五种方法详解
2022/06/14 Redis