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 相关文章推荐
不用ajax实现点击文字即可编辑的方法
Dec 16 Javascript
juqery 学习之四 筛选查找
Nov 30 Javascript
基于mootools 1.3框架下的图片滑动效果代码
Apr 22 Javascript
Moment.js 不容错过的超棒Javascript日期处理类库
Apr 15 Javascript
瀑布流布局并自动加载实现代码
Mar 12 Javascript
jquery及原生js获取select下拉框选中的值示例
Oct 25 Javascript
JQuery实现表格动态增加行并对新行添加事件
Jul 30 Javascript
Bootstrap树形组件jqTree的简单封装
Jan 25 Javascript
全面解析多种Bootstrap图片轮播效果
May 27 Javascript
jQuery Ajax使用FormData对象上传文件的方法
Sep 07 Javascript
解决vue2 在mounted函数无法获取prop中的变量问题
Nov 15 Javascript
Vue源码分析之Vue实例初始化详解
Aug 25 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
对盗链说再见...
2006/10/09 PHP
PHP读取ACCESS数据到MYSQL的代码
2011/05/11 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
2015/04/26 PHP
不安全的常用的js写法
2009/09/15 Javascript
JavaScript事件类型中焦点、鼠标和滚轮事件详解
2016/01/25 Javascript
AngularJs中route的使用方法和配置
2016/02/04 Javascript
Treegrid的动态加载实例代码
2016/04/29 Javascript
Node.js环境下编写爬虫爬取维基百科内容的实例分享
2016/06/12 Javascript
js拼接html字符串的注意事项
2016/10/13 Javascript
前端js实现文件的断点续传 后端PHP文件接收
2016/10/14 Javascript
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
2017/06/09 Javascript
基于JS对象创建常用方式及原理分析
2017/06/28 Javascript
vue-devtools的安装步骤
2018/04/23 Javascript
vue内置组件transition简单原理图文详解(小结)
2018/07/12 Javascript
vue-dplayer 视频播放器实例代码
2019/11/08 Javascript
Vue中的nextTick作用和几个简单的使用场景
2021/01/25 Vue.js
跟老齐学Python之总结参数的传递
2014/10/10 Python
Python使用QQ邮箱发送Email的方法实例
2017/02/09 Python
基于Python的XSS测试工具XSStrike使用方法
2017/07/29 Python
Python使用装饰器进行django开发实例代码
2018/02/06 Python
Python基于socket模块实现UDP通信功能示例
2018/04/10 Python
python遍历一个目录,输出所有的文件名的实例
2018/04/23 Python
对python中dict和json的区别详解
2018/12/18 Python
python json.loads兼容单引号数据的方法
2018/12/19 Python
PyTorch搭建多项式回归模型(三)
2019/05/22 Python
使用apiDoc实现python接口文档编写
2019/11/19 Python
使用python 的matplotlib 画轨道实例
2020/01/19 Python
TensorFlow Saver:保存和读取模型参数.ckpt实例
2020/02/10 Python
pycharm开发一个简单界面和通用mvc模板(操作方法图解)
2020/05/27 Python
关于python的缩进规则的知识点详解
2020/06/22 Python
Django rest framework分页接口实现原理解析
2020/08/21 Python
25道Java面试题集合
2013/05/21 面试题
《坐井观天》教学反思
2016/02/18 职场文书
幼儿园科学课教学反思
2016/03/03 职场文书
深入理解以DEBUG方式线程的底层运行原理
2021/06/21 Java/Android
jackson json序列化实现首字母大写,第二个字母需小写
2021/06/29 Java/Android