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