hashAnchor

文章目录

hash 路由锚点

浏览器在通过 # 改变 url 的时候(比如 a 标签锚点),会不可避免(至少到本文时间 2023-07-21 是如此)地改变页面的滚动位置,没有办法可以阻止这个行为。即使通过监听 hashchange 来 preventDefault 事件也不会生效。

所幸,浏览器的 location 提供了 pushState 和 replaceState 方法,如果通过这两个方法改变 hash,是不会导致页面跳转的。(当然 history 对象也可以)

用例:

1
location.pushState('', '', hashUrl)

但如果使用这种方法,会导致 vue-router 无法监听到 route 的改动,所以这个属性也不会触发响应式的变化。

我发现 VuePress 内部实现了这样的改变 # 路由页面不滚动的方法,去翻看了一下源码,发现 Vue Router 中存在一个 scrollBehavior 的属性,允许自定义路由跳转时页面滚动的位置,或者是否触发。之后发现它可以返回一个 { el: hashName } 的对象用作滚动,我就知道这也是使用了 pushState ,移除了 # 的影响,之后再自己使用 window.ScrollTo 来做一个手动跳转。其实和我自己的实现是一致的,只是自己的实现无法告知 Vue Router。

另外尝试了一种办法:监听 hashchange

所有 # 路由不再特殊处理,只是在页面滚动时候。记录当前位置,在 hash 跳转的时候,页面已经做完滚动更新之后,再自己使用 scrollTo 跳转到之前记录的位置,从而看上去位置没有变化,但实际上这种方法页面会有一个一闪而过的效果,体验不是很好,就没有用上。

分享到:

评论完整模式加载中...如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理