虽然您希望在被问到之后的几年里找到了自己的解决方案,但我给出了一个适当的答案,因为我有一个类似的问题需要解决。
基本上有两种不同的方法可以满足您的标准(这也恰好是我的标准!)。这两者对元素类型都很灵活(它们不仅仅适用于 <a> 元素)。
(对于这两种解决方案,假设该类working-links
被应用于您希望在其中具有功能链接的任何容器元素。请记住,虽然这两个示例都是基于document
用作目标容器以防止链接工作, 让目标更精致通常更有意义,比如包裹页面主要内容区域的任何东西)
第一个是禁用文档上的所有默认单击操作,然后(基本上)在适当的容器上重新启用它们。
这在实践中的工作方式是将事件处理程序应用于文档对象本身(或包含需要阻止的所有内容的任何元素 - 这将是最好的,这样站点菜单/等仍然可以在不需要更改的情况下工作)。事件向上冒泡:您不需要在每个链接上都有一个事件处理程序,您只需要在文档上使用一个事件处理程序来拦截对链接的任何点击。
我们可以利用这种行为将另一个事件处理程序附加到我们希望单击在其中工作的任何容器上(例如,一个具有 类的容器working-links
),以防止单击事件传播到附加到文档对象的处理程序。
$(document).on("click", function(event) {
event.preventDefault();
});
$(".working-links").on("click", function(event) {
event.stopPropagation();
});
codepen.io 上附带 HTML 的示例
请注意,我提供了这些 usingon()
而不是click()
因为如果您的目标不是整个文档并且可能动态插入更多目标区域(AJAX/等),它允许轻松地将这些更改为委托事件。这仅在您选择更有选择性地绑定事件时才重要:在文档级别,其中的任何更改都无关紧要,并且仍然会被事件绑定捕获,因为它们仍然会正确冒泡。
这对于工作链接事件可能更重要:如果您在绑定后动态地向页面添加更多内容,则需要适当地更改它以添加选择器。on()
如果您尝试附加处理程序,然后有选择地将其从适当分类的项目中删除,或者如果您尝试仅将处理程序附加到没有类的元素(使用 CSS 选择器:not
或通过使用 限制 jquery 选择.not()
),则此冒泡行为是为什么它不起作用。即使您不将 附加event.preventDefault()
到链接或其容器,如果它附加到它们的任何祖先,它也会冒泡到它们并且仍然会阻止该操作。
另一种方法是将单击事件处理程序应用于文档/主容器元素,然后应用依赖于event.target
.
这个非常简单,但可能没有那么优雅。
我们将简单地捕获文档(或您选择定位的任何容器)上的所有点击事件,并确定 event.target 是否包含在我们的排除元素之一中。最简单的方法可能是使用 jquery 的is()
函数。
要记住的一件事是,您不仅需要检查 是否event.target
在与类选择器匹配的元素集中,还要检查类选择器的所有子元素:否则嵌套在直接子元素之外的任何 <a> 元素都将失败去工作。
$(document).on("click", function(event) {
if (! $(event.target).is($(".working-links, .working-links *").children())) {
event.preventDefault();
}
});
codepen.io 上附带 HTML 的示例
从好的方面来说,此方法不需要任何更改即可在动态页面中运行,至少对于添加working-links
分类元素而言。如果您要添加更多非单击容器,显然需要对其进行适当调整以使on()
调用使用委托模式(请参阅有关事件绑定的相应 jQuery 文档)。
不利的一面是,这将比其他方法使用更多的资源用于事件处理程序(以便在每次运行时计算 jQuery 元素集)。在大多数情况下,我们可能不在乎,但这并不是一件坏事。