移动端屏幕适配常用方案的原理解析

前言

前端人员在做移动端开发时经常要考虑屏幕适配的问题。如果开发用的是Vue等一些前端框架,那么webpack等一些工程化工具会提供好多用于移动端适配的插件。知其然而不知其所以然,对于一个人的成长是不利的,所以查阅了好多资料总结了移动端屏幕适配方案的原理,在这里分享给大家。(原生js实现)

移动端屏幕适配之简单适配方案

简单代码实现
var ratio = 18.75; //设定系数是为了方便px与rem的换算,750的设计稿系数一般都为18.75
var viewWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth; //不同浏览器获取视口宽度的方式不同,||运算符就是做了兼容性处理
document.documentElement.style.fontSize = viewWidth/ratio+‘px’; //规定1rem=?px
没错就这么几行代码就完成了,但是缺点是每次视口宽度改变都要手动刷新页面才能看到变化,可利用js函数化编程思想进行优化。

利用函数化编程思想优化
px2rem(); //项目打开就单位转化
window.addEventListener(‘resize’,px2rem);//监测到屏幕尺寸变化就重新执行函数
function px2rem(){
var ratio = 18.75;
var viewWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth;
document.documentElement.style.fontSize = viewWidth/ratio + ‘px’;
}
还是有缺陷,该方法只在当前html代码中有效,如果其他的页面也需要做页面适配呢?更好的方案是将代码抽离出来封装为一个js文件。
js文件是抽离出来了,由于js不像java一样方法前可以加private,public等访问限定修饰符,所以就存在这样几个问题,多个js变量命名相同的问题和我们设置的一些参数(如:ratio)可以被随意修改的问题。
如果不考虑代码复用性差的问题(因为我们还是希望一些变量是可以共享的),一种好的解决方案就是匿名函数闭包来解决。

利用匿名函数闭包的思想对代码再次优化
所谓闭包的本质就是一个立即执行函数

(function(){
vpx2rem();//项目打开就单位转化
window.addEventListener(‘resize’,px2rem);//监测到屏幕尺寸变化就重新执行函数
function px2rem(){
var ratio = 18.75;
var viewWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth;
document.documentElement.style.fontSize = viewWidth/ratio + ‘px’;
}
})();

好了,移动端简单屏幕适配方案就完成了。但是,简单适配方案在高清的屏幕下存在1px边框的问题,给用户不好的体验。毕竟随着技术的发展,给用户更好的体验已经成为前端开发人员的共识,因此通用适配方案是一种应用更为广泛的适配的方案。

通用适配方案就是在做移动端屏幕适配的时候将设备的dpr考虑进去,在单位转化的同时考虑屏幕的缩放,主要利用meta标签中的一些缩放属性。

移动端屏幕适配之通用适配方案

//对多次用到的数据再赋值,避免每次都写的大长
var docEl = document.documentElement;
//通过Css3新增的属性选择选择带viewport的meta标签
var viewPortEl = document.querySelector(“meta[name=‘viewport’]”);
//获取设备的dpr
var dpr = window.devicePixelRatio || 1; //获取不到时默认为1
//对dpr做简单处理,因为设备dpr不一定为整数,为了方便计算我们忽略小数部分
dpr = dpr >= 3 ? 3 : (dpr >= 2 ? 2 : 1);
//为了方便操作将dpr设置为自定义属性
docEl.setAttribute(‘data-dpr’,dpr);
//计算出不同dpr下的缩放比
var scale = 1/dpr;
//存放缩放语句
var content = ‘width=device-width,initial-scale=’+scale+’,user-scale=no,maximum-scale=1,minimum-scale=1’;
//为了防止用户恶意的缩放,通常要设置一个最大/小宽度
var maxWidth = 540;
var minWidth = 320;
docEl.setAttribute(‘max-width’,maxWidth);
docEl.setAttribute(‘min-width’,minWidth);
//判断mate标签中是否有viewport属性,没有就创建
if(viewPortEl){
viewPortEl.setActive(‘content’,content);
}else{
viewPortEl = document.createElement(‘meta’);
viewPortEl.setAttribute(‘name’,‘viewport’);
viewPortEl.setAttribute(‘content’,content);
document.head.appendChild(viewPortEl);
}
px2rem();//项目打开就单位转化
window.addEventListener(‘resize’,px2rem);//监测到屏幕尺寸变化就重新执行函数
function px2rem(){
var ratio = 18.75;
var viewWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth;
document.documentElement.style.fontSize = viewWidth/ratio + ‘px’;
}

通用适配方案也完成了,由于考虑了设备像素比(DPR),可能有些复杂。
如果你不知道移动端适配时meta标签里的内容,下面也给出来了。
<meta name=“viewport” content=“width=device-width,initial-scale=1.0,user-scale=no,maximum-scale=1,minimum-scale=1”>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值