美文网首页
移动端屏幕适配

移动端屏幕适配

作者: zhuyx0304 | 来源:发表于2021-03-29 11:05 被阅读0次

    1、什么是rem

    rem(font size of the root element)是指相对于根元素(<html>)的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于自身的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。

    2、为什么用rem适配

    由于移动端的屏幕众多,就拿iphone来说,iphone5、iphone6、iphone6+分别是360px、375px、414px...Android机的分辨率更是百花齐放...面对这么多的屏幕,px显然不能轻易去适配了,比如设置div的

    padding-left为10px时,iphone5中比例和设计稿一致,但iphone6+则显得有点“瘦”了,因此我们要想着去适配不同屏幕的手机,让设计稿在分辨率相差很大的手机上显示的效果也要一样。

    早期的适配用百分比+媒介查询写很多类型的css代码,这时候的代码量很大,适配效果也不是很好,毕竟机型太多...这时候rem的优势就充分展示出来了...不同分辨率的屏幕,通过动态设置rem的值(即根元素的字体大小),就能实现等比例缩放的效果。

    3、怎么用rem

    计算rem的方式大致分为两种:手淘的flexible和网易的rem.js (都是早期用法,现在已改版);还有一种不用js计算,使用vw单位,一行css代码搞定;
    网易与手淘方案:

    1)、网易:

    第一:设置视口

    <meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
    第二:在dom ready以后,通过以下代码设置html的font-size:

    var deviceWidth = document.documentElement.clientWidth;
    if(deviceWidth > 640) deviceWidth = 640;
    document.documentElement.style.fontSize = deviceWidth / 6.4 + ‘px‘; // 6.4是根据设计稿/100 算出来的 具体值由设计稿定

    目前小米的官网就是这种:

    !function(n){
    var e=n.document,
    t=e.documentElement,
    i=720,
    d=i/100,
    o="orientationchange"in n?"orientationchange":"resize",
    a=function(){
    var n=t.clientWidth||320;n>720&&(n=720); // 720的设计稿
    t.style.fontSize=n/d+"px"
    };
    e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
    }(window);

    2)、手淘:

    第一、判断head中是否设置了viewport,如果有设置,按照已有viewport 设置缩放比

    if (metaEl) {
    console.warn('将根据已有的meta标签来设置缩放比例');
    var match = metaEl.getAttribute('content').match(/initial-scale=([\d.]+)/);
    if (match) {
    scale = parseFloat(match[1]);
    dpr = parseInt(1 / scale);
    }
    }
    第二、如果没有设置meta viewport,判断是否设置dpr,如果有,通过dpr计算缩放scale

    var content = flexibleEl.getAttribute('content');
    if (content) {
    var initialDpr = content.match(/initial-dpr=([\d.]+)/);
    var maximumDpr = content.match(/maximum-dpr=([\d.]+)/);//maximum 设置最大值,与initial的值比较,取最小值;
    if (initialDpr) {
    dpr = parseFloat(initialDpr[1]);
    scale = parseFloat((1 / dpr).toFixed(2));
    }
    if (maximumDpr) {
    dpr = parseFloat(maximumDpr[1]);
    scale = parseFloat((1 / dpr).toFixed(2));
    }
    }

    第三、如果 dpr &scale都没有设置,那么就通过设备的dpr设置起缩放 scale

    if (!dpr && !scale) {//meta[name="viewport"]&&meta[name="flexible"]都不存在。
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
    // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
    if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
    dpr = 3;
    } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
    dpr = 2;
    } else {
    dpr = 1;
    }
    } else {
    // 其他设备下,仍旧使用1倍的方案
    dpr = 1;
    }
    scale = 1 / dpr;
    }

    第四、得到scale之后 ,如果meta 的viewport不存在,那么就创建一meta[name=“viewport”],将scale配置进去

    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); // width=device-width,可省略

    if (docEl.firstElementChild) {
    
        docEl.firstElementChild.appendChild(metaEl);
         
    }
    

    第五、动态改写html的font-size

    var width = docEl.getBoundingClientRect().width;//获取html的宽度
    if (width / dpr > 540) {//判断屏幕逻辑像素大于540时,取540
    width = 540 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;

    vw单位方案:

    //750px设计稿
    html{
    font-size: 13.3333vw;//(100px/750px)*100vw
    }

    相关文章

      网友评论

          本文标题:移动端屏幕适配

          本文链接:https://www.haomeiwen.com/subject/bnavhltx.html