背景
文档从背景页切换到编辑页面的时候,需要记住当前浏览的位置
方案一:
- 记住文档区域滚动的scrollTop
window.addEventlister('scroll', () => {
sessionStore.setItem(`${pageID}ScrollTop`)
})
- 跳转到编辑页面的时候恢复滚动位置
const scrollTop = sessionStore.getItem(`${pageId}ScrollTop`)
缺点:
- 只读页面和编辑页面,宽度不一致的时候,就会定位不到正确的位置,比如语雀那样子
方案二:
原理:
- 首先取到可视区域中最顶部的dom元素(利用
IntersectionObserver) - 计算第一步中dom元素,可视区域占总高度的百分比
应用:
const clientRect = targetDom.getBoundingClientRect()
- 根据第一步中取到的dom元素, 计算元素底部距离顶部的距离:clientRect.y
- 加上第二步中的百分比,计算出高度,clientRect.height * Number(ratio)
- 两者相加就是页面应该滚动的距离
实现:
- 阅读页
页面滚动的时候记住顶部可见区域的第一个dom元素
// 取出顶部可见区域的第一个dom元素
let intersectionObserver = new IntersectionObserver(
function(entries) {
let matchEntry: IntersectionObserverEntry | null = null
entries.forEach((entry: IntersectionObserverEntry) => {
if (entry.boundingClientRect.y < entry.rootBounds!.y) {
if (!matchEntry) {
matchEntry = entry
} else if (entry.time >= matchEntry.time) {
matchEntry = entry
}
}
})
// matchEntry 即时目标dom
// do something
},
{
root: scrollDom,
rootMargin: '0',
threshold: [0]
}
)
// 监听子元素
Array.from(children).forEach(children => {
intersectionObserver.observe(children)
})
然后计算dom可视区域的高度占总高度的比例
const baseTopOffset = 0 //滚动区域距离页面顶部的距离
const clientRect = targetDom.getBoundingClientRect()
if (clientRect.bottom > baseTopOffset && clientRect.top < baseTopOffset) {
const scrollTop = clientRect.y - baseTopOffset
const ratio = Math.abs(scrollTop) / clientRect.height
}
- 编辑页
const baseTopOffset = 0 //滚动区域距离顶部的距离
const clientRect = dom.getBoundingClientRect()
const top = clientRect.y - baseTopOffset
const domOffset = clientRect.height * Number(ratio) // 计算出第一步中顶部dom可见高度
scrollDom.scrollTo(0, top + domOffset)