2011-07-25 78 views
0

我有以下的jQuery擴展:jQuery的擴展和停止的setInterval()

var particleTimer = 0; 
jQuery.fn.particleEmitter = function (num, wid, hei, rad, tme, rep) { 
    particleTimer = setInterval(function() { 
     //appends elements... 
    }, 500); 
}; 

jQuery.stopParticleEmitter = function() { 
    clearInterval(particleTimer); //this doesn't stop it... 
} 

clearInterval()似乎不工作...

這裏是我的完整代碼一個小提琴: http://jsfiddle.net/neuroflux/wtJFj/3/

注意,「粒子」實際上不會移動,因爲它需要的文檔寬度...

但計時器應清除的onmouseout ...的d不......

+0

你可以嘗試添加particleTimer至$對象,因此它是全球可用 - 所以'$ .particleTimer = setInterval的(... ' –

+0

他.........:) –

+0

我建議將'particleTimer'變量附加到jQuery對象 - 我可以看到這兩個函數被附加 - 但是'particleTimer'變量不是。我認爲它是根據標準的jQuery插件協議在閉包中聲明的。 –

回答

2

就實際的setInterval而言,你的代碼看起來很好,我看不到任何理由認爲它不起作用,只要你只有一個粒子發射器在任何給定的時間運行。

我之所以會說「一次一個」,是因爲跳出我的第一件事就是您假設沒有人使用您的插件會多次呼叫您的particleEmitter,因爲您使用單個變量作爲句柄。

我會通過返回它來處理呼叫者的責任,而不是自己跟蹤它。

jQuery.fn.particleEmitter = function (num, wid, hei, rad, tme, rep) { 
    return setInterval(function() { 
     //appends elements... 
    }, 500); 
}; 

jQuery.stopParticleEmitter = function(timerHandle) { 
    if (timerHandle !== 0) { 
     clearInterval(timerHandle); 
    } 
    return 0; 
} 

返回的句柄出particleEmitter意味着你不能鏈,但A)你原來不支持鏈接(除非需要返回別的,約定是返回this出的插件功能,鏈接);和B)一個人並不總是需要支持鏈接,如果你有很好的理由返回不同的值。

側面說明:我回到0上面,因爲我傾向於在我的代碼中使用這個成語止動功能:

myHandleVar = jQuery.stopParticleEmitter(myHandleVar); 

顯然,這種風格可能不適合您的口味。 :-)

兩個發射器與手柄的調用跟蹤的Live working example

HTML:

<div id="container1"> 
    <input type='button' class='start' value='Start 1'> 
    <input type='button' class='stop' value='Stop 1' disabled> 
    <p class="target"></p> 
</div> 
<div id="container2"> 
    <input type='button' class='start' value='Start 2'> 
    <input type='button' class='stop' value='Stop 2' disabled> 
    <p class="target"></p> 
</div> 

的JavaScript:

jQuery(function($) { 
    var handles = {}; 

    $("#container1, #container2").each(function() { 
    var $this = $(this); 
    $this.find(".start").click(startClick); 
    $this.find(".stop").click(stopClick); 
    }); 

    function startClick() { 
    var container = $(this).closest('div[id^="container"]'), 
     id = container[0] && container[0].id; 
    if (id) { 
     handles[id] = container.find(".target").particleEmitter(); 
     this.disabled = true; 
     container.find(".stop")[0].disabled = false; 
    } 
     } 

    function stopClick() { 
    var container = $(this).closest('div[id^="container"]'), 
     id = container[0] && container[0].id; 
    if (id) { 
     handles[id] = $.stopParticleEmitter(handles[id]); 
     this.disabled = true; 
     container.find(".start")[0].disabled = false; 
    } 
    } 

    function display(msg) { 
    $("<p>").html(msg).appendTo(document.body); 
    } 

}); 

更新:您問下面關於阻止他們全部。這是很容易做到,只需跟蹤把手你伸手(live example):

(function() { 
    // Our current set of outstanding handles 
    var handles = {}; 

    // Hook up our emitter function 
    jQuery.fn.particleEmitter = function (num, wid, hei, rad, tme, rep) { 
    var target = this, 
     handle; 

    // Start this interval timer 
    handle = setInterval(function() { 
     $("<span>click </span>").appendTo(target); 
    }, 500); 

    // Store the handle in a map 
    handles[handle] = handle; 

    // Return the handle 
    return handle; 
    }; 

    // Our "stop" function 
    jQuery.stopParticleEmitter = function(timerHandle) { 
    if (timerHandle !== 0) { 
     // Clear the timer 
     clearInterval(timerHandle); 

     // Remove the handle from our "outstanding" list 
     delete handles[timerHandle]; 
    } 

    // Return a value the caller can use to clear our their 
    // handle variable. 
    return 0; 
    } 

    // Our "stop all" function 
    jQuery.stopAllParticleEmitters = function() { 
    var handle; 
    for (handle in handles) { 
     if (handles.hasOwnProperty(handle)) { // Largely unnecessary check 
     clearInterval(handle); 
     } 
    } 
    // Clear our outstanding handles. There's no race 
    // condition here, JavaScript on browsers is single-threaded. 
    handles = {}; 
    }; 
})(); 

說明這一切是如何被包裹在一個功能,所以handles變量是私有的,以我們的插件。

+0

這實際上不會影響'setInterval()'雖然它會嗎? –

+0

@Neuro:我沒有看到'setInterval'有任何問題,所以我認爲你必須覆蓋句柄。我剛剛添加了一個活的工作副本。 –

+0

@Neuro:事實上,從你的小提琴中,這正是你正在做的 - 啓動多個發射器,並且每次啓動一個新發射器時覆蓋以前的手柄。 –

1

這小提琴作品:http://jsfiddle.net/7WzzH/

也許是因爲你忘了fn同時宣佈stopParticleEmitter功能?

這裏是修正版本

$.fn.stopParticleEmitter = function() { 
    clearInterval(particleTimer); 
} 

編輯:

當然它不會工作。您在for循環中進行12(!)次迭代,因此使用您的函數只會清除最後一個時間間隔,而您將有11個繼續工作。至少必須使用數組。或者將rep設置爲1,它會起作用。

嘗試rep == 1這裏:http://jsfiddle.net/wtJFj/5/

+0

+1 - 這是修復! – Fenton

+1

不,它不工作 - 它不工作...在問題中查看我的JSFiddle .. –

+0

不,這將無法防止覆蓋的句柄。 –

3

由於這是之前提到的只是保持你的時候,你想殺死他們有他們手柄設置,因此所有定時器的戰績,這裏是你的代碼

的小修改

http://jsfiddle.net/qRheY/

它並不完美。但它的工作原理(去除正弦的事情,因爲它是在我的瀏覽器造成的錯誤)

PS如果你願意,你可以讓處理器在一個陣列中,並摧毀他們在一個循環

http://jsfiddle.net/bnePt/