如何部分地阻止默认事件?

5

有一个带有<a href="#">元素的<label>。我想要阻止<a>元素的默认行为(即导航),但它应该执行<label>元素的默认行为(即选中其中的复选框)。

测试用例:http://jsfiddle.net/3M6WE/。单击foo切换复选框。点击bar不会导航,但也不会切换复选框。

如何使<a>元素不导航但可以切换复选框?我想避免像手动切换复选框这样的hack。如果有的话,我正在寻找一个“部分”preventDefault


4
在<label>标签内放置<a>标签似乎有点奇怪。 - Pointy
2
如果点击“foo”会产生相同的效果,那么链接有什么用处呢? - Reinder Wit
同意@Pointy的观点,那个<a>标签的目的是什么? - VisioN
好的,我减少得太多了。在我的真实应用程序中,链接切换了一个<div>,允许用户输入有关所选选项的更多详细信息。 - pimvdb
4
为什么不直接使用<span>标签而使用<a>标签呢? - xdazz
@xdazz:它的外观和<a>元素不太一样。当然,我可以为<span>设置样式,但如果有一个优雅的解决方案来解决preventDefault问题,那将是更可取的。 - pimvdb
3个回答

4
你可以触发父元素(标签)的点击事件: http://jsfiddle.net/3M6WE/11/
$("a").on("click", function(e) {
    e.stopPropagation();
    $(this).parent().click();
    // do stuff...
    e.preventDefault();
});

然后进行一些操作,最后调用preventDefault()函数。

1
@pimvdb,这是因为原始的、默认被阻止的事件仍然冒泡到DOM树上。在触发新事件之前,在原始事件上调用 stopPropagation() 应该可以解决这个问题。 - Frédéric Hamidi
1
@pimvdb提到的问题是,当您单击“标签”(不是“a”,也不是“input”)时,事件处理程序会执行两次(控制台中有两条消息)。添加stopPropagation并不能防止这种情况。 - James Allardice
这个答案在Safari浏览器中不起作用。请查看下面的我的答案,那个是可行的版本。 - Casey Foster
@Casey Foster:我正在寻找一个Google Chrome的解决方案(我已经标记了这个问题)- 谢谢你的提醒! - pimvdb
我明白了,但我还是有点困惑,为什么你想要添加更多的代码来做同样的事情,而不是删除一些代码呢 =p - Casey Foster
显示剩余7条评论

2

我想你无法阻止这种情况的发生:

来自MDN

嵌套的<label>元素中的单击事件

从Gecko 8.0(Firefox 8.0 / Thunderbird 8.0 / SeaMonkey 2.5)开始,冒泡单击事件最多触发一个<label>,并且合成的单击事件不能触发其他<label>。在Gecko中,单击事件仍将冒泡超过<label>,而在WebKit或Internet Explorer中,单击事件将停止在<label>处。 Gecko 8.0之前的行为(触发多个<label>)导致Firefox停止响应(请参见bug 646157)。


2

现在没有链接,也没有链接点击事件。 - Peter Olson
有点奏效,但仍然可以选择链接文本。但这是一个可行的解决方案,所以+1。 - pimvdb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接