视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用JavaScript实现对象匀速/变速运动的方法_基础知识
2020-11-27 21:09:20 责编:小采
文档
 实例1——控制一个对象的匀速移动和停止

HTML:
代码如下:





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 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 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
}
}

下载本文
显示全文
专题