防止在 href="#" 链接中滚动到顶部

Preventing scroll to top in href="#" links

我正在为页面编写一个插件,以防止 <a href="#"> 在单击时滚动到顶部。

我知道href="#!"href="javascript:void(0);"和点击事件event.preventDefault()都是解

由于页面是动态的,我正在考虑 'absorbing' 所有点击或使用 MutationObserver。目前我已经实施了第一个解决方案(下面的代码)。

我想知道是否有人可以帮助突出每个解决方案的优点和缺点以帮助我做出决定(或者是否有更好的解决方案/改进我的代码)。我关心的是每个解决方案如何随着页面变得更加动态/具有更多节点而扩展。

我觉得像我所做的那样为整个文档添加一个点击事件应该是最好的?

document.body.addEventListener('click', function() {
  var hash = false
  for (const el of event.composedPath()) {
    switch (el.hash) {
      case "":
        hash = true
      case undefined:
        continue
    }
    hash = false
    break
  }
  if (hash) event.preventDefault()
})

为了提供一些上下文,这是一个 html5 游戏,当最忙时,文档中可能有 10000 多个 <a> 标签,并且一次可能有数千个 added/subtracted。我不希望用户在每次点击时或页面因我的插件而发生变化时出现明显的延迟。

您可以使用 Element.closest() 从单击的元素向上遍历 DOM,并使用 href 属性中的特定值定位 link。

如果结果不是 null,那么您可以使用 Event.preventDefault() 取消锚点滚动的发生

document.addEventListener('click', event => {
  const link = event.target.closest('a[href="#"]');

  if (link === null) {
    return;
  }

  event.preventDefault();
});