此问题属于REM的优化
解决如下问题
在移动端rem布局中 , 多数环境多数浏览器下rem的计算妥妥的没有问题 , 但是部分环境 , 比如某些软件内嵌的webview中打开的h5页面 , 由于webview没有设置相应处理 , 导致页面的font-size会收到系统字号大小的影响。
font-size的改变完成会影响页面的rem的展现值 , 所以影响在某种程度上来说还是很严重的,
比如今天就被提了个相关的bug TnT
情况是这样 , 在软件内嵌的h5页面写了一个元素 , 根据特殊的rem计算方式 , 7rem值完全可以展示在各个手机下正常展示 , 但是某些机型的安卓手机 , 就发生了变易 , 异常的大。。。
经检查发现 , html中的font-size值是正常值 ,但是出现了一个匪夷所思的情况!
页面html上的font-size以50px为例 , 在移动端内嵌h5中设置元素height:1rem;最终computed出来的高度竟然是53px。。。
整个人就蒙圈了 , 然后突然灵光一闪 , 发现是系统的字号调大了。。。
系统如何处理的这个font-size展示还没有搞清楚。。。但是我想到了一个解决办法!
(柯南bgm。。。)
页面中html上font-size的值是rem的计算基本单位 , 那么1rem对应的px值就应该等于html的font-size的值;
但是当系统字体放大或缩小后 , rem基准值50px没有变化 , 但是展示值1rem却等于53px , 说明系统将此rem值按某种倍率放大了, 那么我们的最终目的就是让页面保持1rem == 50px就对了
那么我们的目的就是要修改html的基准值算出如何让1rem == 50px
于是可以得出如下计算公式
放大后的1rem对应的px值53px / 正常计算的rem基准值50px = 缩放倍率
缩放倍率 = 目标值1rem的px值50px / 修改之后的rem基准值
又由于 正常计算的rem基准值 == 目标值1rem的px值
所以有 修改之后的rem基准值 = 正常计算的rem基准值 * 正常计算的rem基准值 / 放大后1rem的px值
到此为实现的基本原理.
而实现到代码层面就是
var d = document.createElement(‘div‘);
d.style.cssText="width:1rem;height:0;overflow: hidden;position:absolute;z-index:-1;visibility: hidden;";
document.body.appendChild(d);
var dw=d.offsetWidth; // 1rem的实际展示px值
document.body.removeChild(d);
var html = document.querySelector(‘html‘);
var fz = html.style.fontSize || 0; //正常计算出来的rem基准值 , 可自行修改为rem计算好的值
var realRem = fz;
if(dw != fz){//不相等 则被缩放了
realRem = Math.pow(fz , 2) / dw;
}
html.style.fontSize = realRem + ‘px‘;
到此已经可以计算出不被系统字号影响的rem值了 ;
但是!
这段代码依赖于body的dom元素存在 , 向其内部添加元素检查缩放值;
而很多rem计算是在头部head标签内计算的 , 这个时候很有可能还没有body , 那么这样代码岂不是报错了吗?
于是我想到了一个自己不好解释的方案 , 把上面那段代码 在head中执行的时候 , 放在
setTimeout(function(){ } , 0)
于是问题就迎刃而解了 , 页面也没有二次设置font-size改变rem引发的闪动现象;
欢迎各位大大有问题互相交流 , 哪里有写的部队的地方多多提宝贵意见 , 感谢