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的实现简单的表格中增加或删除下一行
Aug 01 Javascript
JavaScript中实现继承的三种方式和实例
Jan 29 Javascript
js阻止冒泡和默认事件(默认行为)详解
Oct 20 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
Mar 21 jQuery
想用好React的你必须要知道的一些事情
Jul 24 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
Oct 26 Javascript
layui获取多选框中的值方法
Aug 15 Javascript
vue3.0 CLI - 2.5 - 了解组件的三维
Sep 14 Javascript
vue移动端弹框组件的实例
Sep 25 Javascript
JavaScript显式数据类型转换详解
Mar 18 Javascript
webpack的 rquire.context用法实现工程自动化的方法
Feb 07 Javascript
js 闭包深入理解与实例分析
Mar 19 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
E路文章系统PHP
2006/12/11 PHP
php 字符转义 注意事项
2009/05/27 PHP
PHPExcel读取EXCEL中的图片并保存到本地的方法
2015/02/14 PHP
PHP dirname(__FILE__)原理及用法解析
2020/10/28 PHP
通过Javascript创建一个选择文件的对话框代码
2012/06/16 Javascript
jQuery.extend()的实现方式详解及实例
2013/06/29 Javascript
window.open 以post方式传递参数示例代码
2014/02/27 Javascript
JS限制文本框只能输入数字和字母方法
2015/02/28 Javascript
jquery实现美观的导航菜单鼠标提示特效代码
2015/09/06 Javascript
JavaScript简单实现弹出拖拽窗口(二)
2016/06/17 Javascript
canvas实现简易的圆环进度条效果
2017/02/28 Javascript
基于Vue实例对象的数据选项
2017/08/09 Javascript
vue如何解决循环引用组件报错的问题
2018/09/22 Javascript
Vue注册组件命名时不能用大写的原因浅析
2019/04/25 Javascript
layui数据表格重载实现往后台传参
2019/11/15 Javascript
微信小程序canvas开发水果老虎机的思路详解
2020/02/07 Javascript
JS Generator 函数的含义与用法实例总结
2020/04/08 Javascript
[02:51]DOTA2战队出征照拍摄花絮 TI3明星化身时尚男模
2013/07/22 DOTA
[01:44]Ti10举办地公布
2019/08/25 DOTA
让python 3支持mysqldb的解决方法
2017/02/14 Python
Python使用defaultdict读取文件各列的方法
2017/05/11 Python
浅谈Python用QQ邮箱发送邮件时授权码的问题
2018/01/29 Python
Python处理CSV与List的转换方法
2018/04/19 Python
python 通过exifread读取照片信息
2020/12/24 Python
Pandas的数据过滤实现
2021/01/15 Python
实现CSS3中的border-radius(边框圆角)示例代码
2013/07/19 HTML / CSS
美国在线面料商店:Fashion Fabrics Club
2020/01/31 全球购物
TCP/IP的分层模型
2013/10/27 面试题
软件缺陷的分类都有哪些
2014/08/22 面试题
八年级语文教学反思
2014/02/11 职场文书
大学四年个人的自我评价
2014/02/26 职场文书
会计学专业自荐信
2014/06/25 职场文书
如何写股份合作协议书
2014/09/11 职场文书
停课通知书
2015/04/24 职场文书
学生病假条范文
2015/08/17 职场文书
「SHOW BY ROCK!!」“雫シークレットマインド”组合单曲MV公开
2022/03/21 日漫