多端适配

相熟前端开发的肯定会遇到这个问题,屏幕适配!有的我的项目要求同时适配PC、平板和挪动端,那咱们应该是写几套不同的款式,还是只写一套呢?哪一种才是最好的?

其实没有哪一种最好的,还是得依据我的项目的需要来定,个别状况下我是举荐只写一套代码,因为这样能够升高开发成本和保护难度。那么就有个问题,一套代码如何去适配不同设施?尺寸该用什么单位?px?em?rem?

我想大部分人的实现无非就那几种计划:

在页面初始化的时候做判断,毛病是不能响应尺寸的变动,页面须要手动刷新,能够写一个 resize 监听事件,当然极少状况下设施屏幕尺寸会产生扭转

document.addEventListener("DOMContentLoaded", () => {    const design = 750;    const docEl = document.documentElement;    let clientWidth = docEl.clientWidth;    if (utils.clientAgent.isPc) {        // 如果是PC端    }    if (clientWidth > 0) {        docEl.style.fontSize = (clientWidth / design) * 100 + "px";    }}, false);

应用 @media 判断,能够做到尺寸变动的响应,毛病是大量的 @media,可读性较差,保护起来十分麻烦,感觉还不如写几套不同的款式

@media screen and (max-width: 375px) {    ...}@media screen and (max-width: 576px) {    ...}@media screen and (max-width: 768px) {    ...}

装置各种第三方插件,就是配置项比拟多,大多数人抉择的计划

npm install lib-flexiblenpm install px2rem-loader...

以上的几种计划都能够解决屏幕自适应的问题,应用上没什么问题,只不过都是基于 rem 布局计划,对挪动端来说成果是最好的,然而在PC端用 rem 显然不太适合,那有没有方法在PC和挪动端切换的时候主动转换 px 和 rem 单位呢?

Less Functions

参考文档
是否不必 javascript?间接在 less 中实现主动切换?为了实现这个目标,饭吃不好,觉也睡不好,尝试了各种各样的办法,通过 less 各种函数偏方最终实现了。

我用的 less 版本是 3.0,查看最新的版本如同是 4.0 以上了,高版本中多了一些新函数,例如 if、each 等,能更不便的编码,不过既然能用低版本实现,那兼容性必定会更强。

实现办法次要是对 value 进行遍历,length、extract 函数可能辨认空格当成数组对象,遍历找出数字型的值,通过 @media 查问主动切换尺寸单位。

原理不难,用 javascript 分分钟就实现了,然而在 less 中就有点蛋疼了,因为作用域的问题,@media 查问中的函数无奈被内部调用,一开始还是被难住了。

/* 依据不同设施适配属性单位 */.mixin-property-rules(@property, @value, @screenWidth) {    @n: length(@value);    .each(@i, @parent: "") when (@i < @n + 1) {        @arg: extract(@value, @i);        /* 屏幕大于或等于768px的设施 */        .ifNumber() when (isnumber(@arg) = true) and (@screenWidth >= 768) {            @child: unit(@arg, px);        }        /* 屏幕小于768px的设施 */        .ifNumber() when (isnumber(@arg) = true) and (@screenWidth < 768) {            @child: unit(@arg * 2 / 100, rem);        }        /* 非数值属性 */        .ifNumber() when (isnumber(@arg) = false) {            @child: @arg;        }        .ifNumber();        @newValue: ~"@{parent} @{child}";        .ifLast() when (@i = @n) {            @{property}: @newValue;        }        .ifLast();        .each(@i + 1, @newValue);    }    .each(1);}.mixin-property(@property, @value) {    /* 屏幕大于768px的设施 */    @media screen and (min-width: 768px) {        .mixin-property-rules(@property, @value, 768);    }    /* 屏幕小于768px的设施 */    @media screen and (max-width: 768px) {        .mixin-property-rules(@property, @value, 767);    }}html {    font-size: 14px;    /* 屏幕小于768px的设施 */    @media screen and (max-width: 768px) {        font-size: ~"calc(100vw / 1536 * 100)";    }    /* 屏幕小于576px的设施 */    @media screen and (max-width: 576px) {        font-size: ~"calc(100vw / 750 * 100)";    }}

函数调用

.example {    .mixin-property(padding, 10 20 15 30);    .mixin-property(border, 1 solid #000);    .mixin-property(font-size, 16);}// 输入 screenWidth >= 768.example {    padding: 10px 20px 15px 30px;    border: 1px solid #000;    font-size: 16px;}// 输入 screenWidth < 768.example {    padding: .2rem .4rem .3rem .6rem;    border: .02rem solid #000;    font-size: .32rem;}

该函数的长处是你毋庸写单位,只写大小数值,办法会依据设施主动返回单位!如果当前想更改尺寸大小或单位,只需批改函数中的计算逻辑即可,一劳永逸!要说毛病的话就是每个调用的函数在 css 中都会输入 @media 查问语句。

提醒:函数中的 @media 查问和数值计算逻辑都是要依据本人需要编写的,下面只是我写的例子而已

(・`´・) 点赞会有更多原创技术文章分享!