JavaScript —— 实现 对象 匀速/变速运动

实例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');
        clearIntervaltimer); //作用见要点①
        obtn.onclick=function){
            timer=setIntervalfunction){
                var speed=10;
                ifodiv.offsetLeft>=300){ //判断对象边距 到达指定位移则关闭定时器
                    clearIntervaltimer);
                }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 movetoobject,itarget){ var obj=document.getElementByIdobject); clearIntervaltimer); timer=setIntervalfunction){ var speed=0; ifobj.offsetLeft<itarget){ //通过对象距离父级的边距和水平位移量 判断左右位移方向 speed=10; }else{ speed=-10; } ifobj.offsetLeft==itarget){ clearIntervaltimer); }else{ obj.style.left=obj.offsetLeft+speed+'px'; }; },30); }

 

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

 JS:

    var timer=null;
    function movetoobject,itarget){
        var obj=document.getElementByIdobject);
            clearIntervaltimer);
            timer=setIntervalfunction){
                var speed=0;
                ifobj.offsetLeft<itarget){//通过位移量除以10,使speed递减,实现减速停止乘以10则为加速。通过乘除的数字,控制快慢
speed
=itarget-obj.offsetLeft)/10; }else{ speed=-obj.offsetLeft-itarget)/10; } speed=speed>0?Math.ceilspeed):Math.floorspeed);//取整,解决最后不足1px的位移量被忽略的问题 ifobj.offsetLeft==itarget){ clearIntervaltimer); }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 movetoobject,itarget){
        var obj=document.getElementByIdobject);
            clearIntervaltimer);
            timer=setIntervalfunction){
                var speed=0;
                ifobj.offsetLeft<=itarget){
                    speed=7;
                }else{
                    speed=-7;
                }
//设置对象在离目标位置itarget的距离小于speed时,停止运动,同时设置对象的left直接移动到itarget的位置。
                ifMath.absitarget-obj.offsetLeft<=speed)){
                    clearIntervaltimer);
                    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 getAttrobj,attrName){
        var obj=document.getElementByIdobj);
        ifobj.currentStyle){
            return obj.currentStyle[attrName]; //兼容IE
        }else{
            return getComputedStyleobj,false)[attrName]; //兼容FF
        }
    }

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注