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 相关文章推荐
关于UTF-8的客户端用AJAX方式获取GB2312的服务器端乱码问题的解决办法
Nov 30 Javascript
juqery 学习之五 文档处理 插入
Feb 11 Javascript
JavaScript 用cloneNode方法克隆节点的代码
Oct 15 Javascript
javascript中的toFixed固定小数位数 简单实例分享
Jul 12 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
Jun 21 Javascript
浅谈JS中的三种字符串连接方式及其性能比较
Sep 02 Javascript
JQuery实现列表中复选框全选反选功能封装(推荐)
Nov 24 Javascript
jquery ajaxfileupload异步上传插件
Nov 21 jQuery
Vue 使用中的小技巧
Apr 26 Javascript
vue.js 实现输入框动态添加功能
Jun 25 Javascript
原生js实现碰撞检测
Mar 12 Javascript
vue图片裁剪插件vue-cropper使用方法详解
Dec 16 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
拼音码表的生成
2006/10/09 PHP
如何使用php判断服务器是否是HTTPS连接
2013/07/05 PHP
实现laravel 插入操作日志到数据库的方法
2019/10/11 PHP
PHP文件打开关闭及读写操作示例解析
2020/08/06 PHP
JQuery从头学起第一讲
2010/07/04 Javascript
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
JavaScript判断DOM何时加载完毕的技巧
2012/11/11 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
JQuery中根据属性或属性值获得元素(6种情况获取方法)
2013/01/17 Javascript
Node.js文件操作详解
2014/08/16 Javascript
JavaScript中window.showModalDialog()用法详解
2014/12/18 Javascript
干货分享:让你分分钟学会javascript闭包
2015/12/25 Javascript
jQuery+ajax实现实用的点赞插件代码
2016/07/06 Javascript
浅析JS中对函数function的理解(基础篇)
2016/10/14 Javascript
vue-router:嵌套路由的使用方法
2017/02/21 Javascript
jQuery创建及操作xml格式数据示例
2018/05/26 jQuery
element ui table 增加筛选的方法示例
2018/11/02 Javascript
vue实现随机验证码功能(完整代码)
2019/12/10 Javascript
JS函数基本定义与用法示例
2020/01/15 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
通过实例了解Render Props回调地狱解决方案
2020/11/04 Javascript
[01:07:21]NAVI vs VG Supermajor 败者组 BO3 第二场 6.5
2018/06/06 DOTA
[43:26]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第二场 11.20
2020/11/23 DOTA
Django 忘记管理员或忘记管理员密码 重设登录密码的方法
2018/05/30 Python
Python中IP地址处理IPy模块的方法
2019/08/16 Python
Django2 连接MySQL及model测试实例分析
2019/12/10 Python
linux面试题参考答案(3)
2012/09/13 面试题
毕业生机械建模求职信
2013/10/14 职场文书
会计专业自荐信范文
2013/12/02 职场文书
24岁生日感言
2014/01/13 职场文书
春节请假条
2014/04/11 职场文书
个人典型事迹材料
2014/12/30 职场文书
莫言获奖感言(全文)
2015/07/31 职场文书
MySQL表的增删改查(基础)
2021/04/05 MySQL
python通过opencv调用摄像头操作实例分析
2021/06/07 Python