Less中函数的高级应用,PC、Web移动端适配的良药偏方
多端适配
【Less中函数的高级应用,PC、Web移动端适配的良药偏方】熟悉前端开发的一定会遇到这个问题,屏幕适配!有的项目要求同时适配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-flexible
npm 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 查询和数值计算逻辑都是要根据自己需求编写的,上面只是我写的例子而已
(?`ω′?) 点赞会有更多原创技术文章分享!
推荐阅读
- 热闹中的孤独
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 异地恋中,逐渐适应一个人到底意味着什么()
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- “成长”读书社群招募
- 2020-04-07vue中Axios的封装和API接口的管理