移动端适配
收集的一些优化方法,项目中要多尝试 🤔🤔🤔
相对于PC端来说,移动端设备分辨率百花齐放,千奇百怪,对于每一个开发者来说,移动端适配是我们进行移动端开发第一个需要面对的问题。
在移动端我们经常可以在head标签中看到这段代码:
<meta name='viewport' content='width=device-width,initial-scale=1,user-scale=no' />
1
meta的设置其实就是对网页的宽度和浏览器窗口的宽度进行设置。
- width=device-width表示页面宽度与设备视口宽度一致
- initial-scale=1表示页面宽度和网页宽度与设备视口宽度的初始缩放比例
- user-scale=no禁止缩放
# rem方案
rem 是相对于根元素 html 的 font-size 来做计算。通常在页面初始化时加载时通过对document.documentElement.style.fontSize 设置来实现。实现代码如下:
;(function (doc, win) {
let docEl = doc.documentElement;
//考虑以及兼容了 屏幕旋转的事件
let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
let recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth >= 750) {
docEl.style.fontSize = '100px';
} else {
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false); // 屏幕大小以及旋转变化自适应
doc.addEventListener('DOMContentLoaded', recalc, false); // 页面初次打开自适应
recalc();
})(document, window);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上面代码中,clientWidth为750(iphone6)时,1rem=100px。一般设计图的宽度为750px,加入测量尺寸为100px,css代码中可以直接写1rem。
# 1px边框
屏幕的1px(每个物理像素)和css中写的1px之间是有区别的,在普通屏幕下,css的1px对应1物理像素,在2倍屏、3倍屏下1px分别对应2物理像素、3物理像素。
dpr(屏幕像素比,可以理解为每px用多少物理像素显示) = 2就是2倍屏。同样是宽为350px的设备,普通屏看起来正常,2倍屏看起来线条就很粗。如果需要全局都能画出1px的线呢?我们只要保证让1px始终只占1个物理像素就行了。通常通过改变meta标签的viewport的initial-scale值实现。
对于2倍屏设置initial-scale=0.5,对于3倍屏设置initial-scale=0.33,因此,我们还需要在网页渲染前用脚本通过window.devicePixelRatio获取dpr,然后将initial-scale设置为 1/dpr。
(function () {
function resetViewPort() {
var viewport = document.querySelector('meta[name = viewport]');
if (!viewport) {
viewport = document.createElement("meta");
var head = document.querySelector("head");
head.insertBefore(viewport, head.firstChild);
}
var ratio = window.devicePixelRatio || 1;
var content = 'width=device-width,initial-scale=' + Math.round(100 / ratio) / 100 + ',maximum-scale=1,user-scalable=no';
viewport.setAttribute("content", content);
};
window.addEventListener('DOMContentLoaded', resetViewPort);
})()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# px自动转rem
# 完整配置
;(function (doc, win) {
let docEl = doc.documentElement;
//考虑以及兼容了 屏幕旋转的事件
let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
let recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
resetViewPort();
if (clientWidth >= 750) {
docEl.style.fontSize = '100px';
} else {
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
let resetViewPort = function () {
var viewport = document.querySelector('meta[name = viewport]');
if (!viewport) {
viewport = document.createElement("meta");
var head = document.querySelector("head");
head.insertBefore(viewport, head.firstChild);
}
var ratio = window.devicePixelRatio || 1;
var content = 'width=device-width,initial-scale=' + Math.round(100 / ratio) / 100 + ',maximum-scale=1,user-scalable=no';
viewport.setAttribute("content", content);
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false); // 屏幕大小以及旋转变化自适应
doc.addEventListener('DOMContentLoaded', recalc, false); // 页面初次打开自适应
recalc();
})(document, window);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
最近更新时间: 2021/06/17 10:13:36
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00