详解移动端适配

314 阅读2分钟

1. 认识视口

  1. 布局视口: 移动端默认是980px 用于布局的。
  2. 视觉视口: 就是眼睛能够看到的那个部分 不同的屏幕尺寸对应不同的视觉视口。
  3. 理想视口: content="width-device-width"

2. 移动适配端

移动端的屏幕尺寸非常多,我们希望在不同的屏幕尺寸上显示不同的大小

比如:有一个100 * 100的盒子

375: 100*100

320: 90*90

414: 110*110

3. 适配方案

3.1 百分比设置

几乎不用,因为百分比的参照物太多了,往往很难统一

3.2 媒体查询 + rem

根据不同的屏幕尺寸设置html的font-size,其他元素使用rem单位。  

缺点:

  1. 会针对不同的屏幕尺寸编写大量的媒体查询。
  2. 如果动态改变尺寸,不会实时更新。

image.png

3.3 rem + js 动态设置

lib-flexible库中的核心代码 => 淘宝无限适配方案

可以使用px to rem 插件来帮助我们计算  记住在扩展设置中根据你的设计稿尺寸设置font-size的基准值。

默认是16px的,实际开发中,我们会配置postcss-pxtorem插件使用webpack自动帮助我们进行单位转换。

下载px to rem

image.png

扩展设置,修改需要的值,一般为375px => 37.5rem

image.png

使用时,自动计算,选择即可

image.png

步骤:

  1. 获取html元素

const htmlEL = document.documentElement;

  1. 声明设置html元素的字体大小的函数
function setRemSize(){
    const remSize = htmlEL.clientWidth / 10 ;
    // 设置根元素的font-size,也就是rem的值
    htmlEL.style.fontSize = remSize + 'px';
}
setRemSize();
  1. 当屏幕尺寸发生变化的时候,就会调用该函数

window.addEventListener('resize',setRemSize)

3.4 viewport适配方案 => 最推荐的适配方案(用法与rem相同)

将 px 转换为 vw 的源代码

<!DOCTYPE html>
<html>  
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>代码计算器</title>
    <style>
        
    </style>
</head>
<body>
    <form>
        <fieldset>
            <legend>设计稿设置</legend>
            <label>宽:<input type="text" value="375" id="width" /></label><br />
            <label>高:<input type="text" value="667" id="height" /></label><br />
            <button id="setUI">确定</button>
        </fieldset>
        <fieldset>
            <legend>源代码</legend>
            <textarea autofocus name="origin_code" id="origin_code" cols="100" rows="10"></textarea><br />
            <button id="trans">转换</button>
            <label><input type="checkbox" checked id="autoCopy" />自动复制</label>
        </fieldset>
        <fieldset>
            <legend>转换后代码</legend>
            <textarea name="code" id="code" cols="100" rows="10"></textarea><br />
            <button id="copy">复制</button>
            <button id="reset">清空</button>
        </fieldset>
    </form>


    <script>
        function getId(id){
            return document.getElementById(id);
        }
        function getName(name){
            return document.getElementsByName(name)[0];
        }
        var  widthIpt = getId("width");
        var  heightIpt = getId("height");
        var setUIBtn = getId("setUI");


        var origin_code_input = getName("origin_code");
        var transBtn = getId("trans");
        var autoCopyInput = getId("autoCopy");


        var code_input = getName("code");
        var copyBtn = getId("copy");
        var reset = getId("reset");

        var width,height;
        function setUI(){
            width = +widthIpt.value;
            height = +heightIpt.value;
        }
        setUI();


        setUIBtn.onclick = function(e){
            e.preventDefault();
            setUI();
        }


        function copy(text) {
            var textareaEl = document.createElement('textarea');
            textareaEl.setAttribute('readonly', 'readonly'); // 防止手机上弹出软键盘
            // input.setAttribute('value', text);
            textareaEl.value = text;
            document.body.appendChild(textareaEl);
            // input.setSelectionRange(0, 9999);
            textareaEl.select();
            var res = document.execCommand('copy');
            document.body.removeChild(textareaEl);
            console.log("复制成功");
            return res;
        }


        function trans(originCode){
            console.log(originCode);
            var code;
            var reg = /(\d+(.\d+)?)px/gi;
            code = originCode.replace(reg, function(px,num){
                // 100vw = width px   ->   1px = 100vw/width
                // console.log(px, num);
                return (num * 100 / width).toFixed(3) + "vw";
            });


            return code;
        }


        transBtn.onclick = function(e){
            e.preventDefault();
            var res = trans(origin_code_input.value);
            code_input.value = res;
            if(autoCopy){
                copyAndReset(res);
            }
        }
        origin_code_input.onkeypress = function (e){ 
            if(e.keyCode == 13){
                var res = trans(origin_code_input.value);
                code_input.value = res;
                console.log(autoCopy);
                if(autoCopy){
                    copyAndReset(res);
                }
            }
        }
        
        var autoCopy = autoCopyInput.checked;
        autoCopyInput.onchange = function (e){
            autoCopy = autoCopyInput.checked;
        }


        function copyAndReset(code){
            copy(code);
            origin_code_input.value = "";
        }
        
        copyBtn.onclick = function(e){
            e.preventDefault();
            copyAndReset(code_input.value);
        }


        reset.onclick = function (e){
            e.preventDefault();
            code_input.value = "";
            origin_code_input.value = "";
        }
    </script>
</body>
</html>