2017-11-11 35 views
1

我在index.html近六成過濾器按鈕,每個都連有$().click()事件處理程序。jQuery的:如何確保事件處理程序連接到所有相關的元素在DOM

$(document).ready(function() { 
    $('.filter_button_class').click(function(e) { 
     console.log("filter button clicked"); 
     e.preventDefault(); 
    }); 
}); 

在我的CSS文件中,:active選擇確保被點擊時,它的過濾器按鈕會變成藍色。

現在的代碼工作正常,大部分的時間。當瀏覽器首次加載index.html時,事件處理程序似乎都正確連接,代碼始終按預期工作。這是一個單頁的應用程序,所以當用戶點擊後退按鈕返回到index.html在過濾器上的一個按鈕再次點擊,它確實會變成藍色,但.click()處理程序中的代碼有時不執行。

我懷疑這可能是因爲當index.html被重新加載,用戶點擊過濾器按鈕前,不是所有的點擊處理得到重視。但是當用戶再次點擊相同的過濾器按鈕(總共兩次)時,處理程序通常會執行。

問題有沒有辦法讓代碼在click()之內等待執行,直到所有的事件處理程序被首先連接?

而不是.click()我自己也嘗試.on()但這並沒有影響。也可能是我所識別的問題(事件處理程序附加到元素太慢)是錯誤的,但我當然會很感激任何反饋。

+0

當然,如果你動態地添加它們,而不是在HTML中定義它們,那就不一樣了。具體來說,它[會是這個](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements)。 –

+0

@ T.J.Crowder感謝您的反饋。如果通過「動態添加它們」表示這些元素本身,則HTML濾鏡按鈕都不是靜態的。你是說'ready'回調通常可以確保所有的事件處理程序都會附加到它們的元素上嗎? – orlando21

+0

所有'ready'保證的是,當DOM被完全解析時,你給它的回調將被調用。我想我知道你的情況發生了什麼;看到我更新的答案。 :-) –

回答

2

我可以看到所描述的行爲的唯一解釋是,HTML是如此之大,它需要一段時間的瀏覽器來完成解析,並創建DOM。雖然這樣做,它會部分渲染頁面。通過使用ready,你告訴jQuery你不希望你的回調中的代碼被調用,直到該過程完成。這給用戶留下了一個(小)機會窗口,用戶可以看到一個按鈕並在點擊處理程序被附加之前單擊它(因爲DOM解析仍在進行,所以ready回調尚未觸發)。這符合描述的症狀,特別是第一次點擊不起作用(ready還沒有開啓),但後來的一次(同時觸發了ready)。

如果這是發生了什麼,你可以使用事件代表團等待ready回調避免:

$(document).on("click", ".filter_button_class", function() { 
    // ...handle the click... 
}); 

掛接上document一個單擊處理程序,將只被解僱如果點擊通過了.filter_button_class元素。如果確實如此,那麼您的處理程序名爲,好像您已將該事件掛鉤在該元素上。

這涉及到違反腳本規則之一,即在關閉</body>標記之前將它們放在HTML末尾。相反,特別是因爲我們正在處理所造成的HTML的大小和DOM構建時間的問題,我們會打破這種規則,並把script標籤有問題的內容上面:

<script src="jquery.js"></script> 
<script src="yourcode.js"></script> 
<!-- problematic (large) content --> 

再次,正常我們不會這樣做,因爲它使得DOM解析器等待腳本被提取,但在這種情況下,作爲對已知問題的響應,沒有問題。 (只要確保啓用緩存和工作。)

你可以看到this fiddle通過(使用ready)比較this fiddle效果(使用委派的前期處理,然後還可以通過添加ready直接處理)。首先,如果你很快,你可以點擊一個按鈕,讓它不顯示任何東西。第二,如果你很快,你可以點擊一個按鈕,只獲得「委託:」消息,但稍後如果你點擊你會得到一個「直接:」消息,然後是「委託:」一個。

+0

這個downvoter喜歡分享一些關於**如何**的反饋,這是沒有用的嗎? –

+0

我認爲你的建議是現貨,因爲我沒有看到相反的證據。我仍在研究您的解決方案,但想要詢問您的緩存意味着什麼。你的意思是簡單地把JavaScript放在單獨的文件中 - 加載一次,然後他們仍然在記憶中,或者你有其他的東西嗎?謝謝! – orlando21

+0

@ orlando21:我的意思是確保(例如)你從一個設置遠期緩存頭的源碼加載jQuery,以便瀏覽器可以將它保存在緩存中。 (和你自己的腳本一樣,如果它在一個單獨的文件中)。 –

相關問題