让你的锚点跳转位置更精确
Author: Byron Last Updated: 2023-04-02
拦截事件默认行为, 自定位跳转位置, 避免在header固定时锚点的跳转会被header遮挡
目录
问题
在 html 页面中锚点跳转默认时会将指向的锚点位置放在页面顶部, 但是当页面有固定的 header 时, 会被遮挡, 这时候我们需要自定义锚点跳转的位置, 使其不被遮挡.
解决
拦截锚点跳转事件默认行为
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener('click', (event) => {
event.preventDefault()
// do something
})
})
// 或者利用冒泡做事件委托也可以
document.querySelector('parent-of-a').addEventListener('click', (event) => {
if (
event.target
&& event.target instanceof HTMLAnchorElement
&& event.target.hash.startsWith('#')
) {
event.preventDefault()
// do something
}
})
获取锚点跳转目标元素
// 对 hash 进行解码
const hash = decodeURIComponent(event.target.hash)
const target = document.querySelector(hash)
跳转到目标元素
window.scrollTo({
top: target.offsetTop - 100, // 这里的 100 为 header 的高度
behavior: 'smooth',
})
向浏览器历史记录添加新的记录
这一步是为了让浏览器的前进后退按钮能正常工作
history.pushState(null, null, event.target.hash)
完整代码
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener('click', (event) => {
event.preventDefault()
try {
// 解码这一步会有失败的可能, 这里使用 try catch 进行捕获
const hash = decodeURIComponent(event.target.hash)
const target = document.querySelector(hash)
window.scrollTo({
top: target.offsetTop - 100,
behavior: 'smooth',
})
history.pushState(null, null, event.target.hash)
}
catch (error) {
console.error(error)
}
})
})