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 相关文章推荐
jQuery使用技巧简单汇总
Apr 18 Javascript
javascript实现单击和双击并存的方法
Dec 13 Javascript
angularJS 中$attrs方法使用指南
Feb 09 Javascript
jQuery的remove()方法使用详解
Aug 11 Javascript
easyui Droppable组件实现放置特效
Aug 19 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
Nov 13 Javascript
jQuery的内容过滤选择器学习教程
Apr 18 Javascript
常用的9个JavaScript图表库详解
Dec 19 Javascript
把vue-router和express项目部署到服务器的方法
Feb 21 Javascript
vue脚手架搭建过程图解
Jun 06 Javascript
微信小程序实现滚动加载更多的代码
Dec 06 Javascript
javascript实现智能手环时间显示
Sep 18 Javascript
详解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
分享3个php获取日历的函数
2015/09/25 PHP
一键生成各种尺寸Icon的php脚本(实例)
2017/02/08 PHP
PHP编程快速实现数组去重的方法详解
2017/07/22 PHP
smarty模板的使用方法实例分析
2019/09/18 PHP
html数组字符串拼接的最快方法
2009/09/16 Javascript
JavaScript Eval 函数使用
2010/03/23 Javascript
javascript中用星号表示预录入内容的实现代码
2011/01/08 Javascript
javascript检测浏览器flash版本的实现代码
2011/12/06 Javascript
jquery快捷动态绑定键盘事件的操作函数代码
2013/10/17 Javascript
js文本框输入点回车触发确定兼容IE、FF等
2013/11/19 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
2015/02/28 Javascript
javascript中利用柯里化函数实现bind方法
2016/04/29 Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
2017/01/09 Javascript
javascript设计模式之单体模式学习笔记
2017/02/15 Javascript
jquery实现图片平滑滚动详解
2017/03/22 jQuery
vue 过滤器filter实例详解
2018/03/14 Javascript
Vue 获取数组键名的方法
2018/06/21 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
2019/06/18 jQuery
Javascript作用域和作用域链原理解析
2020/03/03 Javascript
python中私有函数调用方法解密
2016/04/29 Python
python数据结构之链表的实例讲解
2017/07/25 Python
python中的计时器timeit的使用方法
2017/10/20 Python
Python用sndhdr模块识别音频格式详解
2018/01/11 Python
python 中if else 语句的作用及示例代码
2018/03/05 Python
浅谈Python批处理文件夹中的txt文件
2019/03/11 Python
python使用pygame模块实现坦克大战游戏
2020/03/25 Python
TensorFlow——Checkpoint为模型添加检查点的实例
2020/01/21 Python
巴西补充剂和维生素购物网站:Natue
2019/06/17 全球购物
工程安全员岗位职责
2014/03/09 职场文书
外语专业毕业生自荐信
2014/04/14 职场文书
活动宣传策划方案
2014/05/23 职场文书
倡议书的写法
2014/08/30 职场文书
单位员工收入证明样本
2014/10/09 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
最感人的道歉情书
2015/05/12 职场文书
公司转让协议书
2016/03/19 职场文书