REM如何无视手机系统字号调整

此问题属于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引发的闪动现象;

欢迎各位大大有问题互相交流 , 哪里有写的部队的地方多多提宝贵意见 , 感谢

    原文作者:敖爽
    原文地址: https://segmentfault.com/a/1190000012348926
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞