2011-10-07 26 views
1

我想使用setInterval來動畫一些事情。首先,我希望能夠指定一系列頁面元素,並讓它們設置背景顏色,這將逐漸淡出。一旦顏色恢復正常,計時器就不再需要了。使用setInterval創建一個可以自行清理的定時器?

所以我有

function setFadeColor(nodes) { 
    var x = 256; 
    var itvlH = setInterval(function() { 
    for (i in nodes) { 
     nodes[i].style.background-color = "rgb(0,"+(--x)+",0);"; 
    } 
    if (x <= 0) { 
     // would like to call 
     clearInterval(itvlH); 
     // but itvlH isn't in scope...? 
    } 
    },50); 
} 

而且情況複雜的是我希望能夠有這回事的多個實例。我在想,也許我會把實時間隔處理程序放到一個數組中,並在他們「死去」時將其清理乾淨,但我怎麼知道他們什麼時候執行?只有在時間間隔內,我才知道它何時完成。

有什麼可以幫助的是,如果有辦法從閉包內部獲得間隔的句柄。

或者我可以做這樣的事情?

function intRun() { 
    for (i in nodes) { 
    nodes[i].style.background-color = "rgb(0,"+(--x)+",0);"; 
    } 
    if (x <= 0) { 
    // now I can access an array containing all handles to intervals 
    // but how do I know which one is ME? 
    clearInterval(itvlH); 
    } 
} 
var handlers = []; 
function setFadeColor(nodes) { 
    var x = 256; 
    handlers.push(setInterval(intRun,50); 
} 
+0

在你的榜樣,爲什麼不_itvlH_在範圍?您正在依賴_x_處於相同功能的範圍內,並且它們在相同的位置定義。 –

回答

0

我已經使用類似你的第一個塊的代碼,並且它工作正常。此jsFiddle也適用。

1

你的第一個示例將工作非常愉快^ _^

function setFadeColor(nodes) { 
    var x = 256; 
    var itvlH = setInterval(function() { 
    for (i in nodes) { 
     nodes[i].style.background-color = "rgb(0,"+(--x)+",0);"; 
    } 
    if (x <= 0) { 
     clearInterval(itvlH); 
     // itvlH IS in scope! 
    } 
    },50); 
} 

你測試它呢?

+0

不,我沒有測試它。這是非常違反直覺,我認爲它不會工作。我完蛋了。 –

+0

@StevenLu :-P總是在**之前測試**詢問^ _ ^ – Neal

0

我想你可以使用一個小技巧來存儲處理程序。首先製作一個對象。然後將該處理程序設置爲屬性,並稍後訪問該對象的屬性。像這樣:

function setFadeColor(nodes) { 
    var x = 256; 
    var obj = {}; 

    // store the handler as a property of the object which will be captured in the closure scope 
    obj.itvlH = setInterval(function() { 
    for (i in nodes) { 
     nodes[i].style.background-color = "rgb(0,"+(--x)+",0);"; 
    } 
    if (x <= 0) { 
     // would like to call 
     clearInterval(obj.itvlH); 
     // but itvlH isn't in scope...? 
    } 
    },50); 
} 
0

您可以編寫輔助函數,像這樣:

function createDisposableTimerInterval(closure, delay) { 
    var cancelToken = {}; 
    var handler = setInterval(function() { 
     if (cancelToken.cancelled) { 
      clearInterval(handler); 
     } else { 
      closure(cancelToken); 
     } 
    }, delay); 
    return handler; 
} 

// Example: 

var i = 0; 
createDisposableTimerInterval(function(token) { 
    if (i < 10) { 
     console.log(i++); 
    } else { 
     // Don't need that timer anymore 
     token.cancelled = true; 
    } 
}, 2000); 
相關問題