使用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 相关文章推荐
改进:论坛UBB代码自动插入方式
Dec 22 Javascript
理解Javascript_14_函数形式参数与arguments
Oct 20 Javascript
探讨javascript是不是面向对象的语言
Nov 21 Javascript
利用JavaScript实现新闻滚动效果(实例代码)
Nov 27 Javascript
append和appendTo的区别以及appendChild用法
Dec 24 Javascript
jquery自定义滚动条插件示例分享
Feb 21 Javascript
构造函数+原型模式构造js自定义对象(最通用)
May 12 Javascript
JavaScript获取客户端IP的方法(新方法)
Mar 11 Javascript
BootStrapValidator初使用教程详解
Feb 10 Javascript
JavaScript数据结构中串的表示与应用实例
Apr 12 Javascript
Vue中的字符串模板的使用
May 17 Javascript
IntelliJ IDEA编辑器配置vue高亮显示
Sep 26 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函数解决SQL injection
2006/12/09 PHP
php与php MySQL 之间的关系
2009/07/17 PHP
PHP 实现多服务器共享 SESSION 数据
2009/08/15 PHP
php有效防止同一用户多次登录
2015/11/19 PHP
PHP微信分享开发详解
2017/01/14 PHP
javascript 写类方式之六
2009/07/05 Javascript
基于jquery的滚动新闻列表
2010/06/19 Javascript
JavaScript中的一些定位属性[图解]
2010/07/14 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
jquery获取元素索引值index()示例
2014/02/13 Javascript
jquery easyui 结合jsp简单展现table数据示例
2014/04/18 Javascript
chrome浏览器当表单自动填充时如何去除浏览器自动添加的默认样式
2015/10/09 Javascript
JavaScript的Backbone.js框架入门学习指引
2016/05/07 Javascript
Vue.js开发环境搭建
2016/11/10 Javascript
AngularJS 验证码60秒倒计时功能的实现
2017/06/05 Javascript
使用watch监听路由变化和watch监听对象的实例
2018/02/24 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
2018/07/20 Javascript
使用jquery模拟a标签的click事件无法实现跳转的解决
2018/12/04 jQuery
了解JavaScript中let语句
2019/05/30 Javascript
Vue基础学习之项目整合及优化
2019/06/02 Javascript
koa2 用户注册、登录校验与加盐加密的实现方法
2019/07/22 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
[03:28]2014DOTA2国际邀请赛 EG战队官方纪录片
2014/07/21 DOTA
[43:47]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第一场 12.09
2020/12/11 DOTA
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
Python自动生产表情包
2017/03/17 Python
浅谈Python使用Bottle来提供一个简单的web服务
2017/12/27 Python
Python3.4解释器用法简单示例
2019/03/22 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
Mac安装python3的方法步骤
2019/08/09 Python
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
美国沃尔玛网上超市:Walmart
2020/08/14 全球购物
个人找工作的自我评价
2013/10/17 职场文书
房屋产权证明书
2014/10/15 职场文书
护士2014年终工作总结
2014/11/11 职场文书