异步请求动态渲染页面的锚点定位
问题
最近有一个需求点,页面是一张配置化的活动页面,渲染的模块和高度都不固定,会有多个模块组成,需要支持url锚点定位,使页面滚动到屏幕对应模块视口位置
初步实现
理想情况:考虑写一个锚点方法,获取url中query参数锚点标记, 然后寻找到dom元素中该对应的id元素,得到滚动距离offsetTop, 实现手动javascript调用滚动到锚点位置!
anchor() {
const { anchorId } = parseQueryString(window.location.search);
if (anchorId) {
// 找到锚点
let anchorElement = document.getElementById(anchorId);
if (anchorElement) {
window.scrollTo(0, anchorElement.offsetTop - 70);
}
}
}
检查
对于固定高度的页面,这个锚点定位获取的滚动高度是ok的.
但是异步请求渲染的页面,接口请求的模块和图片加载会有一个渲染过程,这时直接获取的offsetTop时机可能早于图片load完成的时机,这时定位的offsetTop滚动距离就会缺失图片等高度的距离,明显有误差的了,无法准确定位到该模块位置
考虑和想法
- 保证锚点定位 调用时机 在异步请求的图片load 之后
- 使用 web API ResizeObserver 监听 body的内容区域模块和图片加载完成导致的高度变化(可能监听会执行多次)
- 尽可能快速的在页面dom重排后完成锚点定位,且需仅执行一次锚点定位(防抖处理)
优化实现思路
思路:
this.myPageBody=document.body;
const createTimer = () => {
return setTimeout(() => {
this.anchor()
}, 300);
};
let timer = createTimer();
// 监听页面高度因为加载发生变化回调
this.mypage = new ResizeObserver((entries) => {
clearTimeout(timer);
timer = createTimer();
});
this.myPageBody.observe(this.myPageBody);
总结
如此便实现异步请求动态渲染页面的锚点定位思路