使用JavaScript 实现对象 匀速/变速运动的方法


Posted in Javascript onMay 08, 2013

实例1——控制一个对象的匀速移动和停止

HTML:

<input id="btn" type="button" value=" Move It ! "/>
    <div id="d1">
        <img id="i1" src="1.jpg" alt/>
    </div>

JS:实现向右运动
var timer=null;
    window.onload=function(){
        var odiv=document.getElementById('d1');
        var obtn=document.getElementById('btn');
        clearInterval(timer); //作用见要点①
        obtn.onclick=function(){
            timer=setInterval(function(){
                var speed=10;
                if(odiv.offsetLeft>=300){ //判断对象边距 到达指定位移则关闭定时器
                    clearInterval(timer);
                }else{
                    odiv.style.left=odiv.offsetLeft+speed+'px';
                }
            },30);
        }
    }

要点:
①if语句的条件不能用“==”运算符,如上述代码,当speed的值为基数如7时,不断增加的左边距不会出现300px值,而是到达294后直接跳到301,导致条件失效,无法停止。
②使用else语句是防止停止移动后,每点击一次按钮,div任会移动一个speed。
③在定时器之前,先关闭一下定时器,防止连续点击按钮时,同时打开多个定时器,使移动速度叠加后更快。

封装:

//object:要移动的对象id   itarget:水平位移位置
   var timer=null;
    function moveto(object,itarget){
        var obj=document.getElementById(object);
            clearInterval(timer);
            timer=setInterval(function(){
                var speed=0;
                if(obj.offsetLeft<itarget){  //通过对象距离父级的边距和水平位移量 判断左右位移方向
                    speed=10;
                }else{
                    speed=-10;
                }
                if(obj.offsetLeft==itarget){
                    clearInterval(timer);
                }else{
                    obj.style.left=obj.offsetLeft+speed+'px';
                };
            },30);
    }

实例2——修改上述封装的函数moveto(),使该对象变速停止

 JS:

var timer=null;
    function moveto(object,itarget){
        var obj=document.getElementById(object);
            clearInterval(timer);
            timer=setInterval(function(){
                var speed=0;
                if(obj.offsetLeft<itarget){//通过位移量除以10,使speed递减,实现减速停止。   乘以10则为加速。通过乘除的数字,控制快慢
                    speed=(itarget-obj.offsetLeft)/10; 
                }else{
                    speed=-(obj.offsetLeft-itarget)/10;
                }
                speed=speed>0?Math.ceil(speed):Math.floor(speed);//取整,解决最后不足1px的位移量被忽略的问题
                if(obj.offsetLeft==itarget){
                    clearInterval(timer);
                }else{
                    obj.style.left=obj.offsetLeft+speed+'px';
                };
                document.title=obj.offsetLeft;
            },30);
    }

要点:
①通过递减speed值,实现变速。
②移动到最后,当像素小于1px时,小于1px的几个值不会被添加(或减去)到对象left中,而是被忽略,所以最终位移量比设定的水平位移位置itarget要少几个像素。解决的办法是进行取整:正数向上取整ceil(),负数向下取整floor()。

 

 扩展:垂直位移的原理和水平位移的相同。

 补充1:
解决speed与itarget不能整除,导致对象不能精确到达itarget位置,而是在其左右抖动问题:

var timer=null;
    function moveto(object,itarget){
        var obj=document.getElementById(object);
            clearInterval(timer);
            timer=setInterval(function(){
                var speed=0;
                if(obj.offsetLeft<=itarget){
                    speed=7;
                }else{
                    speed=-7;
                }
//设置对象在离目标位置itarget的距离小于speed时,停止运动,同时设置对象的left直接移动到itarget的位置。
                if(Math.abs(itarget-obj.offsetLeft<=speed)){
                    clearInterval(timer);
                    obj.style.left=itarget+'px';
                }else{
                    obj.style.left=obj.offsetLeft+speed+'px';
                };
                document.title=obj.offsetLeft;
            },30);
    }

补充2:

offset的Bug:例如offsetWidth,它包含的不只是width,还包含padding和border。当给对象设置了填充或边框时,再将offsetWidth赋值给对象时,就会运动就会有差异。
解决:不用offset,而是通过创建一个兼容IE和FF的函数,获取元素的width属性值,来代替offsetWidth。该函数如下:getAttr()

function getAttr(obj,attrName){
        var obj=document.getElementById(obj);
        if(obj.currentStyle){
            return obj.currentStyle[attrName]; //兼容IE
        }else{
            return getComputedStyle(obj,false)[attrName]; //兼容FF
        }
    }
Javascript 相关文章推荐
JavaScript让IE浏览器event对象符合W3C DOM标准
Nov 24 Javascript
Jquery焦点图实例代码
Nov 25 Javascript
CSS3,HTML5和jQuery搜索框集锦
Dec 02 Javascript
jquery插件NProgress.js制作网页加载进度条
Jun 05 Javascript
jquery div模态窗口的简单实例
May 28 Javascript
JQuery中解决重复动画的方法
Oct 17 Javascript
bootstrap下拉菜单使用方法解析
Jan 13 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
Jul 30 Javascript
详解webpack编译多页面vue项目的配置问题
Dec 11 Javascript
JavaScript中字符串的常用操作方法及特殊字符
Mar 18 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
Aug 10 Javascript
Angular.JS读取数据库数据调用完整实例
Jul 02 Javascript
JavaScript 创建运动框架的实现代码
May 08 #Javascript
jQuery输入城市查看地图使用介绍
May 08 #Javascript
深入Javascript函数、递归与闭包(执行环境、变量对象与作用域链)使用详解
May 08 #Javascript
基于jquery实现拆分姓名的方法(纯JS版)
May 08 #Javascript
jQuery cdn使用介绍
May 08 #Javascript
不用锚点也可以平滑滚动到页面的指定位置实现代码
May 08 #Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
May 08 #Javascript
You might like
PHP中动态显示签名和ip原理
2007/03/28 PHP
typecho插件编写教程(五):核心代码
2015/05/28 PHP
php实现的递归提成方案实例
2015/11/14 PHP
PHP实现常用排序算法的方法
2020/02/05 PHP
Prototype使用指南之form.js
2007/01/10 Javascript
加载 Javascript 最佳实践
2011/10/30 Javascript
select标记美化--JS式插件、后期加载
2013/04/01 Javascript
用nodejs写的一个简单项目打包工具
2013/05/11 NodeJs
两种方法实现在HTML页面加载完毕后运行某个js
2014/06/16 Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
2015/08/15 Javascript
jquery模拟实现鼠标指针停止运动事件
2016/01/12 Javascript
Json解析的方法小结
2016/06/22 Javascript
JQuery EasyUI学习教程之datagrid 添加、修改、删除操作
2016/07/09 Javascript
谈谈jQuery之Deferred源码剖析
2016/12/19 Javascript
WebSocket实现简单客服聊天系统
2017/05/12 Javascript
JavaScript寄生组合式继承实例详解
2018/01/06 Javascript
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
jquery.pagination.js分页使用教程
2018/10/23 jQuery
Vue模板语法中数据绑定的实例代码
2019/05/17 Javascript
微信小程序全局变量改变监听的实现方法
2019/07/15 Javascript
webpack4 optimization使用总结
2019/11/10 Javascript
Vue自定义组件的四种方式示例详解
2020/02/28 Javascript
js实现数据导出为EXCEL(支持大量数据导出)
2020/03/31 Javascript
[01:02:46]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python简单实现控制电脑的方法
2018/01/22 Python
python实现kNN算法识别手写体数字的示例代码
2019/08/16 Python
python设置中文界面实例方法
2020/10/27 Python
解决html5中的video标签ios系统中无法播放使用的问题
2020/08/10 HTML / CSS
雪花秀美国官方网站:韩国著名草本护肤化妆品品牌
2016/10/19 全球购物
数控技术与应用毕业生自荐信
2013/09/24 职场文书
环境工程大学生个人的自我评价
2013/10/08 职场文书
工程管理专业个人求职信范文
2013/12/07 职场文书
简历自我评价怎么写好呢?
2014/01/04 职场文书
教师先进事迹材料
2014/12/16 职场文书
小班下学期个人总结
2015/02/12 职场文书
python3实现Dijkstra算法最短路径的实现
2021/05/12 Python