今天我们公司的一个前端让我去写移动端的代码,问我想使用什么来布局,我就说使用 REM ,来布局。结果他没让我去封装,他自己去封装了。然后我就用他封装好的代码开始写移动端了,一起步发现布局不对, REM 没有生效当时没来得及细看,当时我在学 OAuth2.0 第三方登录,没心思去看而且当时也是下午快下班了。现在回来一查果然写错了,而且就我自己来讲当时学这个估计也是不太明白不然没理由当时没有想到错在那里。
开搞:
一、视口约束概念
很久很久之前的前端开发。久到什么时候呢。久到那时候还没有移动端。甚至是诺基亚以前的时代。当时的前端(那时候还不叫前端)也就只负责浏览器网页的开发。而且那个时候电脑的分辨率也不是太高。所以网页在设计的时候,考虑到电脑的分辨率,网页的主体内容即版心一般以 980PX 作为通用版心。所以那个时候的视口约束主要是针对浏览器。PC 的视口约束就等于我们眼睛看到的可视化视口(也叫视觉视口)也就是前端的布局视口。
1.1 PC 端的可视视口
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<h3></h3>
</head>
<body>
<script>
function getViewPort(){
var width = document.documentElement.clientWidth;
var height = document.documentElement.clientHeight;
document.getElementsByTagName("h3")[0].innerHTML = `浏览器的可视宽度为:${width}可视高度为:${height}`;
}
// 初始化调用一次
getViewPort();
// 浏览器窗口改变调用
window.onresize = getViewPort;
</script>
</body>
</html>
PC 端的布局视口检测:
PC端
注意注意 PC 端网页全屏的时候,网页的可视化布局视口宽度是恰好是等于电脑的分辨率:
看了上图,你是不是想说:你的电脑真垃圾。。。
接下来就是一个故事,竖起耳朵听:
-
大家都知道,互联网的发展是先有PC端的浏览器,后来才有移动端的浏览器。在苹果手机还没有出现之前,只有 PC 端的网页,但是随着科技的发展,乔布斯发明了苹果手机。大家就可以使用苹果手机的浏览器来上网。但是有一个问题急需解决,就是当时苹果手机刚出来,大部分的网站设计的时候没有移动端,都是 PC 端的网页。所以当时乔布斯为了方便人们在手机端也能顺利的浏览网页。就明确人为的规定手机的布局视口为980PX。为什么是 980PX 呢?因为当时的网页。大部分使用的都是 980PX 的通用版心。所以如果手机浏览器布局视口是 980PX 的话正好整个手机能够全部内嵌 PC 端的网页直接卡在主版心,不会出现网页只显示部分的情况。那你一定会说这个网页内嵌到手机里面,因为布局视口只有 980px ,虽然手机屏幕的分辨率很大,但网页的字整体会显得非常小,甚至小到看不见,所以。手机支持放大与缩小来查看。
-
再后来,又随着科技的发展。用户都知道手机的分辨率明显比电脑要高很多,但是为什么布局视口只有 980PX 把网页显得非常小,查看网页的时候必须把它放大,很不方便。所以就出现了一个 meta 标签。使用 meta 标签,可以检测到手机浏览器厂商提供的视觉视口大小,一般在 320px ~ 480px 之间,把布局视口由 980px 缩小近一半左右变成视觉视口,来更好的显示文字和图片。
-
与此同时,我们知道。世界上的手机厂商可不止苹果这一家。就算是苹果这一家,它的手机也包括不同的型号,比如苹果 6,苹果 7,等等,每一款手机的视口都是不一样的。更何况还有其他的手机厂商。那么,手机厂商提供的视觉视口大小都不一样,虽然有一个范围。
-
具体到前端在开发的时候,一般来讲 UI 只提供一个型号手机的模板。如果前端只写这一个手机的型号,不去考虑其他型号的手机。那么,当其使用其他手机的用户打开这个网页的时候,网页就会出现适配问题,为了解决这个问题,出现了 RMB 布局。
二、移动端
布局视口
永远 980px ,当年乔布斯定的。
测试代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<h3></h3>
</head>
<body>
<script>
function getViewPort(){
var width = document.documentElement.clientWidth;
document.getElementsByTagName("h3")[0].innerHTML = `不加视口标签,手机浏览器的宽永远为:${width}`;
}
// 初始化调用一次
getViewPort();
// 浏览器窗口改变调用
window.onresize = getViewPort;
</script>
</body>
</html>
测试结果:
我把浏览器调成移动开发环境。手机的型号我设置成自定义(responsive)。我们可以看到,当我在拉动手机视口大小的时候。上面浏览器的模拟数据一能检测到视口的变化,但是。我们通过 javascript 写的代码一直显示视口为 980PX。
视觉视口
加上一个 meta 视口标签。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<title>Document</title>
<h3></h3>
</head>
<body>
<script>
function getViewPort(){
var width = document.documentElement.clientWidth;
document.getElementsByTagName("h3")[0].innerHTML = `手机厂商提供视觉视口为:${width}`;
}
// 初始化调用一次
getViewPort();
// 浏览器窗口改变调用
window.onresize = getViewPort;
</script>
</body>
</html>
再次测试:
可以看到浏览器模拟手机的视口宽度,随着我鼠标拖动一直在改变,同时我们通过 JS 检测的视口宽度也一直在,随着浏览器的数据在联动变化。这时候布局视口已经变成视觉视口。
REM 布局代码
这是我们公司 UI 给的移动端的设计图,定宽为 750PX。
接下来,我们就要做一道数学题。我们知道 UI 给的这个移动端样本。总宽为 750(preWidth)。假设这个样本里面有一个盒子,它的宽为 100(preSize)。750 比上100,就应该等于用户浏览器的视觉视口宽(viewportWidth )比上用户浏览器里面的相对应的一个100(x)的盒子的宽。求出的 x 就设置为 HTML 根元素的 font-size。之后使用 css 提供的 rem。
源代码如下:
function setFontSize(preWidth,preSize){
var viewportWidth = document.documentElement.clientWidth;
document.documentElement.style.fontSize = `${viewportWidth / preWidth *preSize}px`;
}
// 初始化调用一次
setFontSize(750,100);
// 浏览器窗口改变调用
window.onresize = ()=>setFontSize(750,100);
相应的,我们在实际的开发中,假设原型图上给的一个盒子距离浏览器左边框的距离为35px。那么我们在写代码的时候就用写成 0.35 rem
。
最后写到这里,REM 其实就已经写完了。最近想起的文章特别多。但是有想法啊,就是不写,老是写了一半,总是被别的事情耽误,容易忘。看到这里,你肯定会发现,这次文章的文字特别多。其实文字不是我打的。这篇文章的文字,大部分都是使用微信的语音输入法转换的。你还别讲这种写作方法,速度就是快。
最最后吐槽下上个月的工资还没发。。。
2019年11月28日23:54:12
网友评论