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数组定义方法
Sep 10 Javascript
jquery xMarquee实现文字水平无缝滚动效果
Apr 29 Javascript
jQuery在ul中显示某个li索引号的方法
Mar 17 Javascript
JavaScript类继承及实例化的方法
Jul 25 Javascript
javascript自动恢复文本框点击清除后的默认文本
Jan 12 Javascript
angularjs自定义ng-model标签的属性
Jan 21 Javascript
js事件冒泡、事件捕获和阻止默认事件详解
Aug 04 Javascript
Javascript 高性能之递归,迭代,查表法详解及实例
Jan 08 Javascript
bootstrap组件之按钮式下拉菜单小结
Jan 19 Javascript
js仿淘宝商品放大预览功能
Mar 15 Javascript
jQuery鼠标悬停内容动画切换效果
Apr 27 jQuery
React Navigation 使用中遇到的问题小结
May 08 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
表单复选框向PHP传输数据的代码
2007/11/13 PHP
CodeIgniter框架URL路由总结
2014/09/03 PHP
详解如何在云服务器上部署Laravel
2017/06/30 PHP
jquery遍历input取得input的name
2009/04/27 Javascript
JQuery里面的几种选择器 查找满足条件的元素$(&quot;#控件ID&quot;)
2011/08/23 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
javascript读取xml实现javascript分页
2013/12/13 Javascript
js获取checkbox复选框选中的选项实例
2014/08/24 Javascript
jQuery异步获取json数据方法汇总
2014/12/22 Javascript
jQuery实现简单二级下拉菜单
2015/04/12 Javascript
JS实现生成会变大变小的圆环实例
2015/08/05 Javascript
jQuery.uploadify文件上传组件实例讲解
2016/09/23 Javascript
基于Phantomjs生成PDF的实现方法
2016/11/07 Javascript
JavaScript定时器制作弹窗小广告
2017/02/05 Javascript
jQuery导航条固定定位效果实例代码
2017/05/26 jQuery
Javascript(es2016) import和require用法和区别详解
2017/08/11 Javascript
vue2.0 better-scroll 实现移动端滑动的示例代码
2018/01/25 Javascript
dts文件中删除一个node或属性的操作方法
2018/08/05 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
JavaScript 对引擎、运行时、调用堆栈的概述理解
2018/10/22 Javascript
详解vantUI框架在vue项目中的应用踩坑
2018/12/06 Javascript
详解如何在vscode里面调试js和node.js的方法步骤
2018/12/24 Javascript
ES6函数实现排它两种写法解析
2020/05/13 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
探索Python3.4中新引入的asyncio模块
2015/04/08 Python
Python程序运行原理图文解析
2018/02/10 Python
pandas条件组合筛选和按范围筛选的示例代码
2019/08/26 Python
Django之富文本(获取内容,设置内容方式)
2020/05/21 Python
python入门:argparse浅析 nargs='+'作用
2020/07/12 Python
如何实现一个python函数装饰器(Decorator)
2020/10/12 Python
div或img图片高度随宽度自适应的方法
2020/02/06 HTML / CSS
美国医疗用品、医疗设备和家庭保健用品商店:Medical Supply Depot
2018/07/08 全球购物
理货员的岗位职责
2013/11/23 职场文书
Spring中的使用@Async异步调用方法
2021/11/01 Java/Android
Nginx+Tomcat负载均衡多实例详解
2022/04/11 Servers