DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript基礎知識 >> setTimeout實現動畫的黃金優化法則
setTimeout實現動畫的黃金優化法則
編輯:JavaScript基礎知識     
1、使用遞歸思想實現setTimeout的輪詢動畫:在每一次執行方法的時候都重新的設置一個定時器,然後在指定時間內重新的執行當前的方法
問題:每一次設置的定時器,雖然不執行了,但是還存在呢,浪費性能

->在每一次執行方法的時候首先把上一次創建的定時器清除掉
[案例]
var timer = null;
function move() {
window.clearTimeout(timer);
<js code>
timer = window.setTimeout(move, 10);
}
move();


2、當我們的元素即將到達目標值的時候,我們經常會出現這樣一個問題:走一步比目標值大,但是不走這一步還要比目標值小,這樣的話,浏覽器就會徘徊到底走還是不走->"邊界優化"

->我們的邊界判斷把步長加上:假設多走一步會不會比邊界大,如果大的話,我們讓其直接到邊界即可...
[案例]
function move(tar) {
window.clearTimeout(timer);
var curL = utils.getCss(oDiv, "left");
if (curL < tar) {
if (curL + 7 >= tar) {//->邊界判斷加步長
utils.setCss(oDiv, "left", tar);
return;
}
utils.setCss(oDiv, "left", curL + 7);
}
.....
}

3、如果我們的move方法執行的時候需要傳遞參數,我們可以按照如下的操作寫代碼:
[案例1]
function move(tar){
window.clearTimeout(timer);
<js code>
timer=window.setTimeout(move,10);//->這塊無法傳遞給move參數
}
//->這樣寫不行,因為第二次定時器執行move方法的時候沒有辦法給我們的方法傳遞參數

[案例2]
function move(tar){
window.clearTimeout(timer);
<js code>
timer=window.setTimeout(function(){
move(tar);
},10);
}
->這樣寫可以實現,但是由於作用域的累積嵌套會導致私有的作用域不進行自主銷毀,浪費性能->"作用域嵌套累積問題"

[案例3]
->解決這樣的問題,只需要在move中在定義一個小的方法,把所有需要重復執行的動畫代碼放在小的方法中執行(小的方法是不需要傳遞參數的)
function move(tar){
var _move=function(){
window.clearTimeout(timer);
if(curL<tar){
...
}
timer=window.setTimeout(_move,10);
};
_move();
}
->這樣寫的話,只有move這個方法第一次形成的私有的作用域不銷毀,其余每一次執行_move形成的私有作用域在代碼執行完成後立即銷毀


4、按照上述的代碼改完後,我們發現存在問題了:每一次執行move都會形成一個新的不銷毀的私有的作用域,timer是控制動畫的,但是此時的timer是每個作用域私有的變量
->點擊向左:形成一個不銷毀的私有的作用域A,timer是正在向左的動畫,操作的是oDiv這個元素
->同時點擊向右:形成一個新的不銷毀的私有的作用域B,timer是正在向右的動畫,操作的是oDiv這個元素
問題:一個元素既有向左走的動畫,也有向右走的動畫,原地徘徊了

[源代碼]
function move(tar) {
var timer = null;
var _move = function () {
window.clearTimeout(timer);
<js code>
timer = window.setTimeout(_move, 10);
};
_move();
}

->把timer設置為全局變量即可:因為這樣的話oDiv的每一次動畫用的是同一個timer,這樣保證了第二個動畫開始的時候,會把第一個動畫清除掉,元素同時進行的只有一個動畫了
->但是全局變量使用多了不好,我們可以把timer設置為當前元素的自定義屬性->"把定時器設置為當前元素的自定義屬性,防止同一個元素同時兩個動畫進行"
function move(tar) {
var _move = function () {
window.clearTimeout(curEle.timer);
<js code>
curEle.timer = window.setTimeout(_move, 10);
};
_move();
}
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved