🎧 羽森 / Kent

移动端多个高精度UI的转换bug2024-06-20

接手的项目开发模式采用了混合开发,由于需要高精度还原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 完美解决。