移动端适配

144 阅读3分钟

移动端适配方案

1:flexible rem方案(用的基本不多了)

利用js获取当前浏览器视口 /10 并设置给html的fontSize属性,这样就设定了1rem的标准宽度

弊端就在于现在手机基本是两倍dpr 或者 三倍dpr 而设计图给定的基本是一倍dpr,那么就需要将每个元素根据其dpr的不同来分别进行计算,比较繁琐

function setRemUnit(){
    var rem = document.clientWidth / 10;
    document.style.fontSize = rem px;
}
setRemUnit();

2.vh、vw方法

vh和vw是将innerWidht 和 innerHeight分成100份 1vh / 1vw 就代表视觉窗口的1%

解决翻转屏问题

v-min 取vw和vh中的最小的一个

v-max 取vw和vh中的最大的一个

vw_design = 750(设备尺寸,根据设计图来,基本都是750)
vw(px){
    (px / design / 2) * 100vw; 
}

3.自适应布局

vw 和 rem相结合

vw_fontSize = 75; //设定初始fontSize,根据图纸来,一般是75
vw_design = 750; //设定初始总像素大小,根据图纸来,一般是75
rem(px){  //设置适配像素 /2是为了适配双倍屏
    (px / vw_fontSize / 2) * 1rem;
}
//font-size 设置为vw单位
html {
    (vw_fontSize / (vw_design / 2)) * 100vw;
    //限制元素的最小值,当视窗像素大小小于320的时候,1rem固定为64px;
    @meida screen and (max-width: 320px){
        font-size: 64px;
    }
    //限制元素的最大值,当视窗像素大小大540的时候,1rem固定为108px;
    @media screen and (min-width:540px){
        font-size: 108px;
    }
    
}

媒体查询(响应式布局)

@media screen and (max-width:400){
    //当页面宽度小于400的时候触发内部css
}
​
@media screen and (min-width:800){
    //当页面宽度大于等于800的时候触发内部css
}

高清适配

1px线的实现***

方法1:使用伪元素+transfrom scalY(.5)

.box {
    position: relative;
    width: 100%;
}
​
.box:after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: red;
    transform: scaleY(.5);
}

方法2:调节viewport标签的 initial-scale 2x = 0.5 3x = 0.33

//js介入
(function (win) {
  win.flex = (baseFontSize, fontscale) => {
    const _baseFontSize = baseFontSize || 100;
    const _fontscale = fontscale || 1;
​
    const doc = win.document;
    const ua = navigator.userAgent;
    const matches = ua.match(/Android[\S\s]+AppleWebkit/(\d{3})/i);
    const UCversion = ua.match(/U3/((\d+|.){5,})/i);
    const isUCHd = UCversion && parseInt(UCversion[1].split('.').join(''), 10) >= 80;
    const isIos = navigator.appVersion.match(/(iphone|ipad|ipod)/gi);
    //获取设备DPR 赋值给变量 dpr
    let dpr = win.devicePixelRatio || 1;
    if (!isIos && !(matches && matches[1] > 534) && !isUCHd) {
      // 如果非iOS, 非Android4.3以上, 非UC内核, 就不执行高清, dpr设为1;
      dpr = 1;
    }
    //根据dpr 反比设置scale  dpr越高 缩放比例 越小  2dpr => scale(.5) 3dpr=>scale(.33)
    const scale = 1 / dpr;
    //获取meta viewport标签
    let metaEl = doc.querySelector('meta[name="viewport"]');
    if (!metaEl) {
      //如果没有 创建一个
      metaEl = doc.createElement('meta');
      metaEl.setAttribute('name', 'viewport');
      doc.head.appendChild(metaEl);
    }
​
    // 设置meta viewport 属性 拼接缩放比例到 content值中
    metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
    //根据缩小倍率 反向 等比放大 html的font-size 保证实际效果一样
    doc.documentElement.style.fontSize = `${_baseFontSize / 2 * dpr}px`;
    document.documentElement.setAttribute('data-dpr', dpr)
  };
})(window);

高清图片适配

随着分辨率的提高,设计师也为不同清晰度的手机设计了不同清晰度的图片,那么为了节约流量,就需要根据当前设备的dpr来设置不同像素的图片

media查询

使用media查询判断不同的设备像素比来显示不同精度的图片:

       .avatar{
            background-image: url(conardLi_1x.png);
        }
        @media only screen and (-webkit-min-device-pixel-ratio:2){
            .avatar{
                background-image: url(conardLi_2x.png);
            }
        }
        @media only screen and (-webkit-min-device-pixel-ratio:3){
            .avatar{
                background-image: url(conardLi_3x.png);
            }
        }
​

只适用于背景图

srcset

使用img标签的srcset属性,浏览器会自动根据像素密度匹配最佳显示图片:

<img src="conardLi_1x.png"
     srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">
​