hybrid App h5二级页面返回的时候保持与一级页面浏览的位置一致
最近在开发公司hybrid app的时候,需要将原本原生的配置中心模块统一变更为H5,做完之后从测试那里反馈回来这样一个问题,当滑到页面底部或中部的时候进入子页面进行设置,返回的时候页面应该定位到离开时候的位置,就是不要回到页面顶部,体验要接近原生。
提出的解决方案:在react生命周期的componentWillUnmount阶段获取当前滚动条的滚动距离,并且将这个数值存储在sessionStorage中,然后在componentWillMount阶段获取之前存储在sessionStorage中当前页面滑动条距离顶端的问题,然后开始采用window.scrollTo方法将当前页面滚动到之前页面停留的位置,即可实现需求。由于这个配置中心模块只有主页面是特别长的需要做这个操作,其他子页面都很短,因此不必考虑会对其他H5页面造成干扰。在chrome上调成手机模式自测没有问题,体验很好,遂上传代码,以为完美的解决了这个问题。然而,实践是检验真理的唯一标准,在打包构建放到stg环境上之后,用安卓手机自测发现报错:scrollTo is not a function,原来安卓的上元素不支持scrollTo的方法。
正确方案:后经反复试验,采用了一个更加周密、可靠的解决方案。首先在组件上监听一个滚动事件。即在componentWillMount阶段使用原生js监听滚动,
document.addEventListener('scroll', this.e.onScrollHandle, false);
constructor中也要注册一下这个方法:
this.e = {
onScrollHandle: this.onScrollHandle.bind(this)
};
具体的滚动事件,将其滚动位置实时记录下来
onScrollHandle(event) {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
localCache.setItem('_device_setting_scroll_' + PAGE_PARAMS.deviceId, scrollTop);
}
此处采用了localCache本地缓存作为存储容器,并且根据当前配置页面的deviceId作为标志位作了区分,防止记录上一台设备的设置页面的滚动位置而影响到下一台设备的设置页面的滚动位置。
在componentDidMount阶段取出记录的滚动条滚动位置,并开始滚动到指定位置,滚动到指定位置后移除记录的key,若用户又开始滚动,则又开始记录,若用户不再滚动,只是打开看一眼,则下次页面会置顶。
let cacheKey = '_device_setting_scroll_' + PAGE_PARAMS.deviceId;
localCache.getItem(cacheKey).then((scrollTop) => {
if(scrollTop){
document.body.scrollTop = document.documentElement.scrollTop = scrollTop || 0;
}
localCache.removeItem(cacheKey);
});
最后,在componentWillUnmount阶段移除监听事件:
document.removeEventListener('scroll', this.e.onScrollHandle);
经测试,IOS和安卓手机都达到了预期效果,圆满修复了此bug。