2013-02-10 21 views
2

當我用backbone.js觸發此事件並嘗試並延遲函數調用時,事件類型從mouseenter更改爲mouseover,控制檯日誌將射出「 mouseenter「,第二個日誌是」mouseover「爲什麼轉換?爲什麼_.delay將我的e.type從mouseenter轉換爲mouseover

app.newsroomPageElementView = Backbone.View.extend({ 
events: { 
    'mouseenter .featured-image': 'imageHover', 
    'mouseleave .featured-image': 'imageHover' 
}, 
imageHover: function (e) { 
     Y.log(e.type); // this outputs out mouseenter 
     _.delay(function(){ 
     Y.log(e.type); // this outputs mouseover 
     }, 500); 
    },  
}); 

是不是因爲500毫秒後,我的鼠標已經「進入」,因此它實際上是一個鼠標懸停,因爲我的鼠標移動到該事件時,其觸發?

+0

嘗試顯式傳遞'e'對象:'_.delay(function(e){...},500,e);' – 2013-02-10 23:53:08

+0

此外,請嘗試'setTimeout'而不是'_.delay'來檢查if這種行爲是由'_.delay'造成的(儘管我不明白它是怎麼回事)。 – 2013-02-10 23:54:45

回答

1

發生這種情況是因爲Backbone向您提供了一個對象的引用,然後它會重用它。

如您所知,mouseenter事件之後是mouseover事件。你沒有mouseover的處理程序,所以通常你不會在意。

當發生mouseenter事件時,將使用此對象e調用您的處理程序。這是對Backbone內某個對象的引用;你記錄它的type,但是你在你的delay處理程序中保留對該對象的引用。

然後,您的事件處理程序返回,並將控制返回給Javascript線程。 mouseover事件觸發。您的代碼可能會忽略它,但Backbone會繼續並重新使用它傳遞給您的對象,並將關於事件的信息放入其中。

然後,您的延遲到期,並且您使用e找出事件的類型......現在它已獲取所有mouseover事件數據,所以這就是您所看到的。

這對我們大家應該是一個有益的教訓。首先,請注意,JS會處理對象引用,如果您存儲的對象不是您的代碼創建的對象,然後中斷該線程,則該對象可能會在您之下發生更改。同樣,如果你有方法返回數組或對象,知道你正在返回對該數組或對象的引用...因此,如果調用代碼改變了所述數組或對象的內容,這可能會把你搞砸;當你擁有一個擁有公共獲取者的私人領域時,這是特別危險的。如果你不小心,你可以交出一個引用,允許代碼改變你的對象的內部,沒有你的意思!

+2

[「mouseenter' JavaScript事件是Internet Explorer專有的,由於該事件的一般效用,jQuery模擬此事件,因此無論瀏覽器如何,都可以使用它。」](http://api.jquery.com/mouseenter /)。我懷疑這個重用單個事件對象是特定於模擬的'mouseenter'和'mouseleave'事件。用一個額外的屬性標記'e'提供了一些提示:http://jsfiddle.net/ambiguous/J2MFd/ – 2013-02-11 00:37:39

+0

那麼最終的判決是什麼?這個函數會有問題,我需要擔心嗎?我的意思是來自微軟網站的例子顯示某些mouseenter事件比鼠標懸停的方式要少,但是由於這個函數在技術上不會被骨幹調用,所以如果事件發生改變,它應該不是問題嗎?它仍然只能在最初的mouseenter上觸發,並且只有在成功的mouseenter之後纔會發生延遲,這需要我在發生反射之前有一個mouseleave。 – Zuriel 2013-02-11 04:08:35

+0

@ZurielAndrusyshyn:你總是可以克隆'e'來避免參考問題。 – 2013-02-11 04:13:06

相關問題