2012-03-08 68 views
4

正如我們所知,從DOM事件處理函數返回false將停止事件的傳播。但是我最近發現,不同元素的行爲在這個事件上有所不同。例如,考慮以下因素:輸入類型之間的DOM/jQuery事件傳播差異

<div id="container"> 
    <input type="checkbox" name="foo" value="1" /> Check me! 
    <br /> 
    <select> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
    </select> 
    <br /> 
    <input type="text" size="30" /> 
</div> 

周圍的容器都返回false click處理:

$('#container').click(function(e) { 
    $('#clicks').append('<span>clicked</span>'); 
    return false; 
});​ 

div,我還可以點擊文本框,輸入文字,並可以仍然點擊下拉菜單來更改其值。但點擊複選框什麼也不做(實際上,這不是真的 - 它檢查框,觸發處理程序,然後取消選中它)。 jsfiddle here:http://jsfiddle.net/4ncaq/

這種行爲在瀏覽器中是一致的,所以我假定它是通過設計的。但是,這裏工作的規則究竟是什麼?我怎樣才能知道在這種情況下其他類型的元素可能會如何表現?

回答

2

當您單擊某個元素時,該事件將繼續傳播該事件,直到某個處理程序決定取消傳播。在這種情況下,當你點擊複選框,這將提高對<input>第一的事件,然後傳播到#container你在哪裏停止傳播。

如果您想取消輸入元素(如複選框或textareas)的傳播,您應該將其綁定到它們的click事件並在該點停止傳播。

編輯

return false還取消了原來的目標元素的默認操作。複選框,鏈接,單選按鈕是默認點擊操作可取消的一些元素。複選框中的點擊事件的默認操作切換複選框的值,而對於select沒有默認點擊操作,這意味着它不會被取消。

我試着找到一個沒有運氣的默認操作列表,但您可以檢查鏈接Is there a standard resource for the "default action" of HTML elements?

+2

這並不能解釋他爲什麼不能勾選複選框,但他可以放下組合。如果點擊處理程序連接到包含複選框的div,那麼爲什麼它會影響複選框。當div點擊處理程序返回false時,事件確實已經過去了複選框嗎? – Archer 2012-03-08 15:06:54

+0

@archer我編輯了答案來解釋默認操作。 – 2012-03-08 15:25:41

+0

太棒了 - 謝謝:) – Archer 2012-03-08 15:27:04

4

你們看到的是傳播,事件「泡沫」了DOM,所以當你點擊你的複選框,它實際上是射擊的#container click事件(以及你可能已經綁定到輸入或其他任何事件父元素)。因爲它是做一次三件事情,當你很可能只希望它做一個

這樣使用虛假的回報是不明確的。它會阻止默認功能,暫停傳播並停止進一步的執行。

這是更好的做法是具體的,並使用從事件對象的方法來防止默認動作或停止冒泡。

event.preventDefault()將停止一些像自錨點擊加載HREF,被檢查等

event.stopPropagation()將取消傳播,該方法適用於像你的情況下,例如停止複選框 - http://jsfiddle.net/4ncaq/1/

返回false的另一個問題是它可能不會被執行,我看到人們在jQuery中犯的常見錯誤是在具有$的錨點上發生單擊事件。ajax()請求,然後返回false以停止瀏覽器加載鏈接的頁面。在這種情況下,如果出現來自ajax()的錯誤(不是響應錯誤,jQuery錯誤 - 通常是拼寫錯誤參數或某事),它將永遠不會返回false;瀏覽器將加載鏈接的頁面。使用e.preventDefault()完全消除了這個問題。