2010-11-30 64 views
9

使用setTimeout時拉入事件對象的最佳方法是什麼?我使用jQuery來處理所有瀏覽器中的事件模型規範化,但我不知道如何讓'e'對象進入checkPos函數。帶事件參數的Javascript setTimeout函數調用?

我當前的代碼:

function MouseDownEvent(e) { 
    *snip* 
    timeoutID = setTimeout(checkPos(e), 500); 
} 
function checkPos(e) { 
    //function uses e on a timeout of 500ms 
    timeoutID = setTimeout(checkPos(e) }, 500); 
} 

目前因爲函數被調用鼠標按下事件代碼工作一次,但隨着用戶移動鼠標永遠不會更新電子對象。 FF的JavaScript錯誤控制檯也聲明它是'一個無用的setTimeout調用(缺少引號圍繞參數?)',但隨後的建議導致它完全失敗。

如何從setTimeout調用中引入'e'事件參數?

編輯:添加在重新運行checkPos功能每500ms

+1

你的代碼,你實際上調用`checkPos`打電話時`setTimeout`(由於函數調用操作符`()`)和它的返回值傳遞給` setTimeout`;該值可能不是對函數的引用,所以`setTimeout`失敗。 – 2010-11-30 13:48:29

回答

7

首先,你爲什麼使用兩個超時?它看起來對我來說的setInterval()會更好

function MouseDownEvent(e) { 
*snip* 
clearInterval(intervalID); 
intervalID = setInterval(function(){checkPos(e);}, 500); 
} 

其次請你澄清這一點:「......但隨着用戶移動鼠標永遠不會更新電子對象。」爲什麼當用戶移動鼠標時會更新事件對象?您只分配了一個mouseDown處理程序。如果你想在每次鼠標移動時做一些事情,那麼你應該使用mouseMove事件,在這種情況下,超時/間隔無論如何都是不必要的。

function MouseMoveEvent(e) { 
//called every time the mouse is moved, event object will contain position 
} 

在JavaScript與往常一樣,你應該尋找一個事件驅動的解決方案第一個也是唯一使用定時處理程序時,你絕對必須的。

*編輯 - 解決問題的運算在意見中提出*

var handler = { 
    i : 0, 
    function : mouseMoveEvent(e) { 
     handler.i++; 
     if (handler.i % 100 == 0) { 
     //Do expensive operations 
     } 
    } 
} 

$(myElement).bind("mousemove", handler.mouseMoveEvent); 
10

嘗試代碼:

function MouseDownEvent(e) { 
    *snip* 
    timeoutID = setTimeout(function(){checkPos(e);}, 500); 
} 
function checkPos(e) { 
    //function uses e on a timeout of 500ms 
} 

EDIT由於OP評論...

要訪問更新後的事件每次checkPos被觸發:

var myNamespace = {}; 

$('body').mousemove(function(e) { 
    myNamespace.mouseEvent = e; 
}); 

function checkPos() { 
    doSomethingWith(myNamespace.mouseEvent); 
} 

timerID = setInterval(checkPos, 500); 
+0

對不起這個答案,但當我重新運行這個代碼把checkPos(e);在每次超時後,它都未能引入更新的e事件。 – 2010-11-30 14:26:17

1

您可以使用咖喱功能,還有一個用於jQuery here

一般情況下,你會這樣:

function foo(a, b) 
{ 
    alert(a + b); 
} 

var bar = curry(foo, 1); 

bar(2); // alerts 3, as if you had called foo(1, 2) 

,所以你可以這樣做:由於咖喱返回一個函數與它的綁定到E的第一個參數

setTimeout(curry(checkPos, e), 500); 

,你可以直接將它傳遞到setTimeout的。

1

至於我可以看到,IE不會允許通過的「事件」對象周圍像你所需要的。

我能想到的唯一解決方法是將預先需要的任何值存儲爲全局變量,然後在延遲函數中檢查該變量。

例如:http://jsfiddle.net/YvYtn/1/

這將顯示最近的X位置,你可以存儲任何你從事件對象的需要。

的JS代碼:

var _lastPosX= null; 
function MouseDownEvent(evt) { 
    if (typeof evt == "undefined" || !evt) 
     evt = window.event; 
    _lastPosX = (evt.clientX || evt.pageX); 
    timeoutID = window.setTimeout("checkPos();", 500); 
} 
function checkPos() { 
    alert(_lastPosX); 
}