實(shí)例1――控制一個(gè)對(duì)象的勻速移動(dòng)和停止
HTML:
<input id="btn" type="button" value=" Move It ! "/>
<div id="d1">
<img id="i1" src="1.jpg" alt/>
</div>
JS:實(shí)現(xiàn)向右運(yùn)動(dòng)
var timer=null;
window.onload=function(){
var odiv=document.getElementById('d1');
var obtn=document.getElementById('btn');
clearInterval(timer); //作用見(jiàn)要點(diǎn)①
obtn.onclick=function(){
timer=setInterval(function(){
var speed=10;
if(odiv.offsetLeft>=300){ //判斷對(duì)象邊距 到達(dá)指定位移則關(guān)閉定時(shí)器
clearInterval(timer);
}else{
odiv.style.left=odiv.offsetLeft+speed+'px';
}
},30);
}
}
要點(diǎn):
①if語(yǔ)句的條件不能用“==”運(yùn)算符,如上述代碼,當(dāng)speed的值為基數(shù)如7時(shí),不斷增加的左邊距不會(huì)出現(xiàn)300px值,而是到達(dá)294后直接跳到301,導(dǎo)致條件失效,無(wú)法停止。
②使用else語(yǔ)句是防止停止移動(dòng)后,每點(diǎn)擊一次按鈕,div任會(huì)移動(dòng)一個(gè)speed。
③在定時(shí)器之前,先關(guān)閉一下定時(shí)器,防止連續(xù)點(diǎn)擊按鈕時(shí),同時(shí)打開(kāi)多個(gè)定時(shí)器,使移動(dòng)速度疊加后更快。封裝:
//object:要移動(dòng)的對(duì)象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){ //通過(guò)對(duì)象距離父級(jí)的邊距和水平位移量 判斷左右位移方向
speed=10;
}else{
speed=-10;
}
if(obj.offsetLeft==itarget){
clearInterval(timer);
}else{
obj.style.left=obj.offsetLeft+speed+'px';
};
},30);
}
實(shí)例2――修改上述封裝的函數(shù)moveto(),使該對(duì)象變速停止 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){//通過(guò)位移量除以10,使speed遞減,實(shí)現(xiàn)減速停止。 乘以10則為加速。通過(guò)乘除的數(shù)字,控制快慢
speed=(itarget-obj.offsetLeft)/10;
}else{
speed=-(obj.offsetLeft-itarget)/10;
}
speed=speed>0?Math.ceil(speed):Math.floor(speed);//取整,解決最后不足1px的位移量被忽略的問(wèn)題
if(obj.offsetLeft==itarget){
clearInterval(timer);
}else{
obj.style.left=obj.offsetLeft+speed+'px';
};
document.title=obj.offsetLeft;
},30);
}
要點(diǎn):
①通過(guò)遞減speed值,實(shí)現(xiàn)變速。
②移動(dòng)到最后,當(dāng)像素小于1px時(shí),小于1px的幾個(gè)值不會(huì)被添加(或減去)到對(duì)象left中,而是被忽略,所以最終位移量比設(shè)定的水平位移位置itarget要少幾個(gè)像素。解決的辦法是進(jìn)行取整:正數(shù)向上取整ceil(),負(fù)數(shù)向下取整floor()。
擴(kuò)展:垂直位移的原理和水平位移的相同。
補(bǔ)充1:
解決speed與itarget不能整除,導(dǎo)致對(duì)象不能精確到達(dá)itarget位置,而是在其左右抖動(dòng)問(wèn)題:
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;
}
//設(shè)置對(duì)象在離目標(biāo)位置itarget的距離小于speed時(shí),停止運(yùn)動(dòng),同時(shí)設(shè)置對(duì)象的left直接移動(dòng)到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);
}
補(bǔ)充2:offset的Bug:例如offsetWidth,它包含的不只是width,還包含padding和border。當(dāng)給對(duì)象設(shè)置了填充或邊框時(shí),再將offsetWidth賦值給對(duì)象時(shí),就會(huì)運(yùn)動(dòng)就會(huì)有差異。
解決:不用offset,而是通過(guò)創(chuàng)建一個(gè)兼容IE和FF的函數(shù),獲取元素的width屬性值,來(lái)代替offsetWidth。該函數(shù)如下: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
}
}