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 年会抽奖程序
Dec 22 Javascript
Javascript查询DBpedia小应用实例学习
Mar 07 Javascript
js获取url参数代码实例分享(JS操作URL)
Dec 13 Javascript
表单提交前触发函数返回true表单才会提交
Mar 11 Javascript
javascript刷新父页面的各种方法汇总
Sep 03 Javascript
基于Jquery实现万圣节快乐特效
Nov 01 Javascript
javascript断点调试心得分享
Apr 23 Javascript
个人网站留言页面(前端jQuery编写、后台php读写MySQL)
May 03 Javascript
浅析Javascript ES6新增值比较函数Object.is
Aug 24 Javascript
微信小程序项目实践之九宫格实现及item跳转功能
Jul 19 Javascript
小程序视频或音频自定义可拖拽进度条的示例代码
Sep 30 Javascript
vue.js实现只能输入数字的输入框
Oct 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
工厂模式在Zend Framework中应用介绍
2012/07/10 PHP
PHP+jquery实时显示网站在线人数的方法
2015/01/04 PHP
PHP数组生成XML格式数据的封装类实例
2016/11/10 PHP
PHP magento后台无法登录问题解决方法
2016/11/24 PHP
基于PHP实现微信小程序客服消息功能
2019/08/12 PHP
js选取多个或单个元素的实现代码(用class)
2012/08/22 Javascript
解决html按钮切换绑定不同函数后点击时执行多次函数问题
2014/05/14 Javascript
JavaScript中的继承方式详解
2015/02/11 Javascript
JavaScript简单遍历DOM对象所有属性的实现方法
2015/10/21 Javascript
jQuery解决浏览器兼容性问题案例分析
2016/04/15 Javascript
关于json字符串与实体之间的严格验证代码
2016/11/10 Javascript
jquery.uploadifive插件怎么解决上传限制图片或文件大小问题
2017/05/08 jQuery
微信小程序实现获取自己所处位置的经纬度坐标功能示例
2017/11/30 Javascript
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
修改Nodejs内置的npm默认配置路径方法
2018/05/13 NodeJs
vue实现codemirror代码编辑器中的SQL代码格式化功能
2019/08/27 Javascript
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
javascript中的with语句学习笔记及用法
2020/02/17 Javascript
小程序websocket心跳库(websocket-heartbeat-miniprogram)
2020/02/23 Javascript
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
python 创建一个空dataframe 然后添加行数据的实例
2018/06/07 Python
Python搭建Spark分布式集群环境
2019/07/05 Python
Django微信小程序后台开发教程的实现
2020/06/03 Python
python框架flask入门之环境搭建及开启调试
2020/06/07 Python
canvas生成带二维码海报的踩坑记录
2019/09/11 HTML / CSS
英国的知名精品百货公司:House of Fraser(福来德)
2016/08/14 全球购物
美国领先的家庭健康检测试剂盒提供商:LetsGetChecked
2019/03/18 全球购物
在求职信中如何凸显个人优势
2013/10/30 职场文书
电气工程及自动化专业自荐书范文
2013/12/18 职场文书
社区网格化管理实施方案
2014/03/21 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
毕业班工作总结
2015/08/10 职场文书
2019请假条的基本格式及范文!
2019/07/05 职场文书
go语言中fallthrough的用法说明
2021/05/06 Golang
python数字图像处理之图像自动阈值分割示例
2022/06/28 Python