使用JavaScript 實現對象 勻速/變速運動的方法

來源:互聯網
上載者:User

執行個體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
}
}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.