续命之移动适配

0

最近看了好多移动适配的资料,整理了一下
以作后续开发少出bug(哈哈~)
移动端布局,为了适配各种大屏手机,目前最好用的方案莫过于使用相对单位rem。
基于rem的原理,我们要做的就是:
针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小(基准值)。
这里我们提取了一个公式(rem表示基准值)
rem = document.documentElement.clientWidth * dpr / 10

如何转换成rem单位呢?
公式如下:
rem = px / 基准值;

rem方案一

首先,先说一个常识,浏览器的默认字体高都是16px。
使用%单位方便使用
css中的body中先全局声明font-size=62.5%,这里的%的算法和rem一样。
因为100%=16px,1px=6.25%,所以10px=62.5%,
这是的1rem=10px,所以12px=1.2rem。px与rem的转换通过10就可以得来,很方便了吧!
使用方法
注意,rem是只相对于根元素htm的font-size,即只需要设置根元素的font-size,其它元素使用rem单位设置成相应的百分比即可;
例子:

clipboard.png
一般情况下,是这样子使用的

clipboard.png
移动端做适配的时候,可以使用这样的方法

clipboard.png

方案二 js中rem是怎么用的

首先得让文字和标签的大小随着屏幕的尺寸做变化 等比缩放,然后在把计算出的值赋给html

clipboard.png
这样当前窗口的字体就能获取到了,然后我们再设置窗口大小改变的情况,其实也就是加一个窗口改变的监听事件onresize。发生了onresize,就重新计算该窗口下根目录字体的大小。

clipboard.png

方案三 从dpr维度的适配

上文也提到了dpr那么什么是dpr呢 通俗点讲就是
花了200px的长宽来渲染CSS里面定义的100px的长宽
而样式pixels和设备pixels的比值,就是dpr,即Device Pixel Ratio
<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
  .box1{
      height: 5rem;
      width: 5rem;
      background-color:red;
  }
</style>

</head>
<body>

<div class="box1"></div>

</body>
<script>
var dpr = window.devicePixelRatio;//当前显示设备的物理像素分辨率与CSS像素分辨率的比值
var meta = document.createElement('meta');

// dpr
meta.setAttribute('content', 'initial-scale=' + 1 / dpr + ', maximum-scale=' + 1 / dpr + ', minimum-scale=' + 1 / dpr + ', user-scalable=no');
document.getElementsByTagName('head')[0].appendChild(meta);

// rem
document.addEventListener('DOMContentLoaded', function (e) {

document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';

}, false);
</script>
</html>
为了防止全局变量污染或者覆盖他人的变量,可封装成模块再使用。

方案四 lib-flexible适配

lib-flexible是一个制作H5适配的开源库
你可以直接使用阿里CDN
<script src="http://g.tbcdn.cn/mtb/lib-fle...{{version}}/??flexible_css.js,flexible.js"></script>
将代码中的{{version}}换成对应的版本号0.3.4。
详情:https://github.com/amfe/artic...

方案五:
与方案三有一曲同工之妙,写得比较全
javascript方式,通过上面的公式,计算出基准值rem,然后写入样式,大概如下

var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');

dpr = window.devicePixelRatio || 1;
rem = docEl.clientWidth * dpr / 10;
scale = 1 / dpr;

// 设置viewport,进行缩放,达到高清效果
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');

// 设置data-dpr属性,留作的css hack之用
docEl.setAttribute('data-dpr', dpr);

// 动态写入样式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';

// 给js调用的,某一dpr下rem和px之间的转换函数
window.rem2px = function(v) {
v = parseFloat(v);
return v * rem;
};
window.px2rem = function(v) {
v = parseFloat(v);
return v / rem;
};

window.dpr = dpr;
window.rem = rem;

最后 字体大小问题

既然上面的方案会使得页面缩放(scale),
对于字体缩放问题,设计师原本的要求是这样的:任何手机屏幕上字体大小都要统一,所以我们针对不同的分辨率(dpr不同),会做如下处理:
font-size: 16px;
[data-dpr="2"] input {
font-size: 32px;
}
(注意,字体不可以用rem,误差太大了,且不能满足任何屏幕下字体大小相同)
为了方便,我们也会用less写一个mixin:

.px2px(@name, @px){
@{name}: round(@px / 2) * 1px;
[data-dpr="2"] & {
@{name}: @px * 1px;
}
// for mx3
[data-dpr="2.5"] & {
@{name}: round(@px 2.5 / 2) 1px;
}
// for 小米note
[data-dpr="2.75"] & {
@{name}: round(@px 2.75 / 2) 1px;
}
[data-dpr="3"] & {
@{name}: round(@px / 2 3) 1px
}
// for 三星note4
[data-dpr="4"] & {
@{name}: @px * 2px;
}
}


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

载入中...