使用rem构建web h5应用 处理chart 和 app webview 在安卓下错乱问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010377383/article/details/82530903

前言

最早基于手淘做过一次H5 rem适配, 当时基于Hybrid APP。后面使用antd-mobile后,使用 阿里的高清方案。css 新增calc 函数 可以处理边框 配合 flex布局。但是字体大小要额外处理,并且部分安卓机型不支持calc,以及1px问题。so,最后我还是决定采用其他的rem。这也是踩坑的开始

内嵌rn webview。

我们为三方提供一个H5授权页,用于oAuth2 认证流程。在上述js计算,在ios下都正常。但是在安卓出现不识别问题。出现问题主要原因如下。

  1. 用rem布局的H5页面
  2. 页面内嵌在APP的webview中
  3. 手机 设置 修改了默认字体大小

后续找到几种解决方案,

(一)获取系统字体大小

一般设计稿750px,为了便于计算,我们设1rem = 100px;也就是1rem = 1 * htmlFontSize (htmlFontSize 为 html 元素的字体大小),当然在iPhone6 375px宽的屏幕上,htmlFontSize 为50px。

其实,htmlFontSize 除了以px为单位外,还可以用百分比作为单位,比如你可以设置htmlFontSize的大小为312.5%,页面的布局效果与设置htmlFontSize 大小为50px是一样的效果。

但是在有些 Android 手机上,浏览器或 webview 的默认字体是随着系统设置的字体改变的。这样就会导致默认字体大于或小于 16px。从这个思路出发,我们只需要找到系统设置的字体大小就可以正确的计算htmlFontSize的值了。所以有了以下获取默认字体大小的函数。

// 获取系统默认字体大小
// designWidth 设计稿的宽度
// rem2px 设计稿宽度下,1rem的宽度
function adapt(designWidth, rem2px){
    var d = window.document.createElement('div');
    d.style.width = '1rem';
    d.style.display = "none";
    var head = window.document.getElementsByTagName('head')[0];
    head.appendChild(d);
    var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width'));
    return defaultFontSize
};

然后配合之前的htmlSize函数

!(function(doc, win, designWidth, rem2px) {
    var docEl = doc.documentElement,
       defaultFontSize = adapt(designWidth, rem2px),
       resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
       recalc = function() {
           var clientWidth = win.innerWidth
                        || doc.documentElement.clientWidth
                        || doc.body.clientWidth;

           if (!clientWidth) return;
           if (clientWidth < 750) {
               docEl.style.fontSize = clientWidth / designWidth * rem2px / defaultFontSize * 100 + '%';

           } else {
               docEl.style.fontSize = '625%';
           }
       };
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);

})(document, window, 750, 100);

总结:这种方式能解决rem在安卓错乱问题,但是会遇到页面字体大小根据系统设置改变的问题,因为iphone6页面其实还是375,没进行放大 然后scale。所以能解决antd-mobile 类似下拉插件需要使用 window.devicePixelRatio 来设置问题,对应chart 图标也不会乱,也可以用rem处理字体,但是在pc打开就很奇怪。

(二)获取html元素实际宽度

参考地址: https://blog.csdn.net/fungleo/article/details/73309396

一般,我们动态计算好html的font-size之后,我们就啥都不干了,就走了。但是,我们现在知道了,我们设置的大小不一定是真实的大小,所以,我们需要在设置完字体大小之后,再去重新获取一下html的font-size,看看实际的这个值,和我们设置的是不是一样。如果不一样,就要根据比例再设置一次。

function htmlFontSize(){
    var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
    var width = w > h ? h : w;
    width = width > 720 ? 720 : width
    var fz = ~~(width*100000/36)/10000
    document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz +"px";
    var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px','')*10000)/10000
    if (fz !== realfz) {
        document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz * (fz / realfz) +"px";
    }
}

总结:这种方案没使用过,可以自己试下。

(三)客户端固定webview字体大小

移动端同学进行处理,在APP内直接设置webview的默认字体大小。
如:在每个webview配置webview.getSettings().setTextZoom(100)就可以了。

类似微信的 iOS 版的调整字体大小使用的是通过给 body 设置 -webkit-text-size-adjust:120% 属性实现的,Android 则是通过 Java 调用 webview 的 API 设置字体大小。

(四)rem 闪屏问题

配合方案一的

@media (min-width: 320px){html{font-size: 266.667%;} }
@media (min-width: 360px){html{font-size: 300%;} }
@media (min-width: 375px){html{font-size: 312.5%;;} }
@media (min-width: 384px){html{font-size: 320%;} }
@media (min-width: 414px){html{font-size: 345%;} }
@media (min-width: 448px){html{font-size: 373.333%;} }
@media (min-width: 480px){html{font-size: 400%;} }
@media (min-width: 512px){html{font-size: 426.667%;} }
@media (min-width: 544px){html{font-size: 453.333%;} }
@media (min-width: 576px){html{font-size: 480%;} }
@media (min-width: 608px){html{font-size: 506.667%;} }
@media (min-width: 640px){html{font-size: 533.333%;} }
@media (min-width: 750px){html{font-size: 625%;;} } 

注意:引入文件时,方案一计算的js文件必须要放在媒体查询的css文件前面,不然就会出现 htmlFontSize 一直都是100%的计算错误


1.html{font-size: 50px;} //这个一定写
2.JS动态计算和密集的媒体查询二选一

猜你喜欢

转载自blog.csdn.net/u010377383/article/details/82530903