JavaScript反弹动画效果的实现代码


Posted in Javascript onJuly 13, 2017

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    #box{
      width:200px;
      height:200px;
      position: absolute;
      top:0;
      left:200px;
      background:lightblue;
    }
    .btn{
      position:absolute;
      top:200px;
      left:100px;
      height:50px;
    }
    .btn input{
      display:inline-block;
      margin-left:50px;
      outline: none;
      width:100px;
      height:50px;
      border:1px solid green;
      cursor:pointer;
    }
  </style>
</head>
<body>
  <div id='box'></div>
  <div class='btn'>
    <input type="button" value='向左' id='btnLeft'>
    <input type="button" value='向右' id='btnRight'>
  </div>
  <script>
    var oBox = document.getElementById("box");
    var minLeft = 0;
    var maxLeft = utils.win('clientWidth')-oBox.offsetWidth;
    var step = 5;
    var timer = null;
    function move(target){
      //target:告诉我要运动的目标位置
      window.clearTimeout(timer);
      var curLeft = utils.css(oBox,"left");
      if(curLeft<target){//向右走
        if(curLeft+step>target){//边界
          utils.css(oBox,"left",target);
          return;
        }
        curLeft+=step;
        utils.css(oBox,"left",curLeft)
      }else if(curLeft>target){//向左走
        if(curLeft-step<target){//边界
          utils.css(oBox,"left",target);
          return;
        }
        curLeft-=step;
        utils.css(oBox,"left",curLeft)
      }else{//不需要运动
        return;
      }
      // timer = window.setTimeout(move,10)//这里有一个问题,点击按钮第一次target的值是有的,但是第二次通过setTimeout执行的时候没有给target进行传值。是undefined
      timer = window.setTimeout(function(){
        move(target);
      },10)//这样使用匿名函数包裹一下,就解决了上面的问题,但是这样写性能不好,因为每一次到达时间的时候,都需要执行一次匿名函数(形成一个私有的作用域),在匿名函数中再执行move,但是move中需要用到的数据值在第一次执行的move方法中,需要把匿名函数形成的这个私有的作用域作为跳板找到之前的,这样就导致了匿名函数形成的这个私有的作用域不能销毁
    }
    document.getElementById('btnLeft').onclick = function(){
      move(minLeft)
    }
    document.getElementById('btnRight').onclick = function(){
      move(maxLeft)
    }
  </script>
</body>
</html>

为了解决上面性能不好的问题,下面是一个优化后的代码:里面在使用一个函数包裹,这样就只有move函数创建的一个私有作用域没有销毁,等到_move执行完毕,move就自然会进行销毁。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    #box{
      width:200px;
      height:200px;
      position: absolute;
      top:0;
      left:200px;
      background:lightblue;
    }
    .btn{
      position:absolute;
      top:200px;
      left:100px;
      height:50px;
    }
    .btn input{
      display:inline-block;
      margin-left:50px;
      outline: none;
      width:100px;
      height:50px;
      border:1px solid green;
      cursor:pointer;
    }
  </style>
</head>
<body>
  <div id='box'></div>
  <div class='btn'>
    <input type="button" value='向左' id='btnLeft'>
    <input type="button" value='向右' id='btnRight'>
  </div>
  <script>
    var oBox = document.getElementById("box");
    var minLeft = 0;
    var maxLeft = utils.win('clientWidth')-oBox.offsetWidth;
    var step = 5;
    var timer = null;
    function move(target){
      //target:告诉我要运动的目标位置
      _move();
      function _move(){
        window.clearTimeout(timer);
        var curLeft = utils.css(oBox,"left");
        if(curLeft<target){//向右走
          if(curLeft+step>target){//边界
            utils.css(oBox,"left",target);
            return;
          }
          curLeft+=step;
          utils.css(oBox,"left",curLeft)
        }else if(curLeft>target){//向左走
          if(curLeft-step<target){//边界
            utils.css(oBox,"left",target);
            return;
          }
          curLeft-=step;
          utils.css(oBox,"left",curLeft)
        }else{//不需要运动
          return;
        }
        timer = window.setTimeout(_move,10);
      }
    }
    document.getElementById('btnLeft').onclick = function(){
      move(minLeft)
    }
    document.getElementById('btnRight').onclick = function(){
      move(maxLeft)
    }
  </script>
</body>
</html>

注意:为了让当前的元素在同一时间只运行一个动画(下一个动画开始的时候首先把上一个动画的定时器清除掉):保证当前元素所有动画接收定时器返回值的那个变量需要共享,有两种方式:1、全局接收(例如上面的代码 var timer = null)2、给元素增加自定义属性(如下图所示)

JavaScript反弹动画效果的实现代码

总结:通过以上可以得出动画优化的四条规则:

1、边界判断加步长

2、清除没有用的定时器

3、在外层函数需要传参的时候,可以在里面在嵌套一层函数,避免作用域的累积。

4、把定时器的返回值存储在元素的自定义属性上,防止全局变量冲突和同一时间多个动画执行

以上所述是小编给大家介绍的JavaScript反弹动画效果的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
说说掌握JavaScript语言的思想前提想学习js的朋友可以看看
Apr 01 Javascript
无缝滚动改进版支持上下左右滚动(封装成函数)
Dec 04 Javascript
js去空格技巧分别去字符串前后、左右空格
Oct 21 Javascript
jQuery的:parent选择器定义和用法
Jul 01 Javascript
JavaScript中的对象的extensible属性介绍
Dec 30 Javascript
ichart.js绘制虚线、平均分虚线效果的实现代码
May 05 Javascript
js数组的五种迭代方法及两种归并方法(推荐)
Jun 14 Javascript
Web打印解决方案之普通报表打印功能
Aug 29 Javascript
Angularjs实现搜索关键字高亮显示效果
Jan 17 Javascript
ES6入门教程之Array.from()方法
Mar 23 Javascript
彻底搞懂并解决vue-cli4中图片显示的问题实现
Aug 31 Javascript
vue实现表格合并功能
Dec 01 Vue.js
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
Jul 13 #Javascript
详解vue-cli + webpack 多页面实例配置优化方法
Jul 13 #Javascript
Angular限制input框输入金额(是小数的话只保留两位小数点)
Jul 13 #Javascript
js实现图片上传预览原理分析
Jul 13 #Javascript
vue.js数据绑定的方法(单向、双向和一次性绑定)
Jul 13 #Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
Jul 13 #Javascript
AngularJS 实现点击按钮获取验证码功能实例代码
Jul 13 #Javascript
You might like
一个php作的文本留言本的例子(一)
2006/10/09 PHP
不用数据库的多用户文件自由上传投票系统(2)
2006/10/09 PHP
php后退一页表单内容保存实现方法
2012/06/17 PHP
php中文字符串截取方法实例总结
2014/09/30 PHP
CodeIgniter钩子用法实例详解
2016/01/20 PHP
jquery实现带二级菜单的导航示例
2014/04/28 Javascript
JQuery中clone方法复制节点
2015/05/18 Javascript
微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解
2016/12/08 Javascript
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
React Native使用Modal自定义分享界面的示例代码
2017/10/31 Javascript
深入浅出webpack之externals的使用
2017/12/04 Javascript
关于vue中watch检测到不到对象属性的变化的解决方法
2018/02/08 Javascript
Vue.set 全局操作简单示例
2019/09/19 Javascript
matplotlib绘制符合论文要求的图片实例(必看篇)
2017/06/02 Python
Python实现字典(dict)的迭代操作示例
2018/06/05 Python
python2与python3共存问题的解决方法
2018/09/18 Python
Django的性能优化实现解析
2019/07/30 Python
python实现一个猜拳游戏
2020/04/05 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
美国现代家具和家居商店:Apt2B
2016/08/29 全球购物
如果NULL定义成#define NULL((char *)0)难道不就可以向函数传入不加转换的NULL了吗
2012/02/15 面试题
国际贸易专业个人求职信格式
2014/02/02 职场文书
警示教育活动总结
2014/05/05 职场文书
药剂专业自荐书
2014/06/20 职场文书
汽修专业自荐信
2014/07/07 职场文书
竞选学习委员演讲稿
2014/09/01 职场文书
小学运动会报道稿
2014/10/04 职场文书
2014年教师工作总结
2014/11/10 职场文书
2014年加油站工作总结
2014/12/04 职场文书
家属答谢词
2015/01/05 职场文书
2015年酒店客房部工作总结
2015/04/25 职场文书
防卫过当辩护词
2015/05/21 职场文书
考生诚信考试承诺书(2016版)
2016/03/25 职场文书
干货:我将这样书写我的演讲稿!
2019/05/09 职场文书
Redis实现订单自动过期功能的示例代码
2021/05/08 Redis
MySql数据库触发器使用教程
2022/06/01 MySQL