接手的项目开发模式采用了混合开发,由于需要高精度还原UI和移动端适配问题,我们一直使用着 amfe-flexible 搭配 postcss-pxtorem 两个库,而这两天在开发中遇到一个页面被放大的 bug,具体复现步骤如下:
从一个H5(A)跳转到了另一个H5(B),再返回去的时候,A页面整个被放大了
值得一提的是,两个H5都是独立的链接,B页面本身是一个独立的入口,比如反馈页面,我的历史记录之类的。A页面有一个锚点可以跳转过去,之前我们项目里从一个H5跳转到另一个H5再返回原来的H5,这种场景之前也有过的,并没有现在出现的放大问题。第一次遇到这种问题我都懵逼了,对接的客户端是新来的,所以先让他排除一下是不是修改了viewport。得知是搬运之前的代码修改的,那应该没问题才对。后续开始找资料,在chatGPT的辅助下,才得知除了viewport,还有根标签 font-size 问题,就着手开始定位是哪边的的问题了。
思考问题
我们知道,amfe-flexible 负责动态设置根元素 html 的 font-size,而 postcss-pxtorem 将 CSS 中的 px 单位转换为 rem 单位。从一个页面跳转到另一个页面时,font-size 的值可能没有被正确重置,也可能设置了错误的值,从而导致页面显示放大或者缩小。但到这我的问题就来了,返回后重新reload,一般来说不是会重新获取rem再进行赋值吗。然后我就翻了一下amfe-flexible的 源码
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
是有监听pageshow的,那rem的值应该是有被设置上了,那剩下的就是 postcss-pxtorem 转换的rem的问题了,看了一下配置,才发现B页面用的rootValue是7.5,而A页面是3.75,由于B页面是两年前开发的,那时候还是用的7.5,去年开始换成3.75,也是刚好有3.75的跳转7.5,再返回去才出现了这种问题,那现在页面都开发好了,要突然修改rootValue的值,再吧所有的css px值修改一下,显然是不现实的,只能做好兼容了,解决办法就是在A项目的main.js加上以下代码:
let fontSize = document.documentElement.style.fontSize;
window.onpageshow = function () {
document.documentElement.style.fontSize = fontSize;
}
amfe-flexible 是将 pxtorem 生成的值动态设置根元素 html 的 font-size,那我们再套一层,等设置好后我们储存下来已设置的 font-size 值,等 pageshow 的时候再次赋值,就不会赋值到B页面的 font-size 了,试了一下,还真行,至此,bug 完美解决。