2012-03-08 72 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()完全消除了这个问题。