前端 | 移动Web深度剖析(下篇)
Posted 唐山程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端 | 移动Web深度剖析(下篇)相关的知识,希望对你有一定的参考价值。
前两天更新了这篇文章的上篇,还没看的同学请点击这里:
很长一段时间对于自适应与响应式很模糊,傻傻分不清楚,都是为了适配移动端,难道两个不是同一个东西么?两者之间到底有什么区别呢?那么如果想要搞明白这个问题,我想先需要了解一下自适应和响应式到底是什么,才能弄明白两者之间的区别。
为了搞清楚这个问题,疯狂谷歌于是找到了这张图,这张图可以说是把自适应与响应式表现的淋漓尽致。
响应式
响应式网站设计是一种网络页面设计布局,其理念是:集中创建页面的图片排版大小,可以智能地根据用户行为以及使用的设备环境进行相对应的布局。(来自百度百科)
个人理解:响应式是web端页面对移动设备的兼容处理。其实现全部依赖于@media(媒体查询)。其作用就是实时的监控设备情况,完成不同的文件操作。@media可以针对不同的屏幕尺寸设置不同的样式,特别是如果你需要设计响应式的页面,@media是非常有用的。当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新对页面进行渲染。
并不是所有浏览器都能很好的支持@media,以下@media在各个浏览器中支持情况。
浏览器支持
浏览器 | 版本 |
---|---|
Chrome | 21.0.0 版本以上 |
IE | 9.0版本以上 |
Firefox | 3.5.0版本以上 |
Safari | 4.0.0版本以上 |
Opera | 9.0.0版本以上 |
<script src="//cdn.bootcss.com/html5media/1.1.8/html5media.min.js"></script>
媒体类型
设备类型形形色色,对于不同的设备该如何去选择处理,@media不仅仅针对于移动设备,下面是@media支持的参数。
all :所有设备
braille :盲文触觉设备
embossed :盲文打印机
print :手持设备
projection :打印预览
screen :彩屏设备
speech :"听觉"类似的媒体类型
tty :不适用像素的设备
tv :电视设备
@media print {
#box {background:green;}
}
这样在手持设备上这个div背景颜色就会变成绿色,在其他的设备上则还保持原有的粉色。So Easy有木有。然而并没有这么简单,想要完成响应式的操作还有大量的工作要去做。
设备屏幕的大小形形色色,大小不一应该以什么规格条件来完成适配呢?
适配条件:
PC端大屏 : 大于等于1200px
PC端中等屏 : 大于等于992px
中等屏(平板) : 大于等于768px
小屏(手机) : 小于768px
对于响应式总结起来也就是利用媒体查询的特性,根据不同的屏幕的大小引入不同的css文件,以达到响应式的目的。
下面是我在使用响应式的时候总结的一些经验:
不要使用固定的宽高
根据不同的屏幕引入不同的css文件
多使用一些浮动布局或弹性布局
尽量不要使用定位
图片的处理,使图片液态化
字体大小不要使用px,使用em后者rem
自适应网页设计指能使网页自适应显示在不同大小终端设备上新网页设计方式及技术。
移动端的适配个说纷纭,如百分比适配,rem适配,vw适配然而这种情况给开发人员带来很头疼的问题,到底应该怎么适配才能响应不同的移动设备。其实,对于WebApp适配的解决方案有很多,在选择上应该如何取舍,今天就这个问题我们来进行简单的阐明。
如下所有示例都是使用同一布局:
<div id="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
百分比 || vw
因为所有的子元素都是的宽度百分比都是按照父级来定的,高度也是如此,如果把子元素宽度设置为100%的,高度不是固定的时候,子元素宽度会铺满整个父元素,里面的内容不统一的时候会出现参差不齐的情况。其中的原理就是,因为媒体查询会实时对当前设备的可视窗口进行检测,4个div的宽度各占父层25%,就此完成适配。
#box {
width:100%;
}
#box:after {
content:'';
display:block;
clear:both;
}
#box div {
width:25%;
min-height:80px;
float:left;
font-size:36px;
line-height:80px;
text-align:center;
color:white;
}
#box div:nth-child(1){
background:red;
}
#box div:nth-child(2){
background:blue;
}
#box div:nth-child(3){
background:green;
}
#box div:nth-child(4){
background:hotpink;
}
使用vw也是如此,width:100vw=width:100%这个实在是有点无脑操作了,不在这里浪费大家太多时间。
利用viewport适配
其实大多数的Web App在开发的时候,利用百分比布局的比较少,也会带来一些小的问题,这时就出现的利用viewport利用窗口的缩放来进行布局。
我们说过initial-scale(初始比例),minimum-scale(最小缩放比例),maximum-scale(最大缩放比例),其实在移动在设置这个属性的时候,并不是把元素给放大了,而是把屏幕按照设置的比例对应的放大,给用户一种错觉,达到页面的放大缩小目的。那么该如何使用viewport进行适配呢?
改动CSS样式:
#box {
width:100%;
}
#box:after {
content:'';
display:block;
clear:both;
}
#box div {
width:80px;
min-height:80px;
float:left;
font-size:36px;
line-height:80px;
text-align:center;
color:white;
}
#box div:nth-child(1){
background:red;
}
#box div:nth-child(2){
background:blue;
}
#box div:nth-child(3){
background:green;
}
#box div:nth-child(4){
background:hotpink;
}
但是如果这样设置的话就无法适应所有的移动设备了,我们应该怎么去做才能让他完全的适配所有的移动设备呢?利用强大的javascript来解决这个问题,还没有JavaScript不能解决的问题
(function() {
//获取到的是移动设备的deviceWidth,即设备屏幕宽度
var _deviceWidth = window.screen.width;
// 希望通过 viewport 把所有页面设置成一致
_targetWidth = 320;
//得到初始和最大最小缩放比例
_scale = (_deviceWidth / _targetWidth);
//创建一个meta标签
oMeta = document.createElement('meta');
oMeta.name = 'viewport'; //可视区域窗口
//把缩放比例赋值给初始化缩放比例最大最小缩放比例
oMeta.content = 'user-scalable=no,initial-scale=' + _scale +
',minimum-scale=' + _scale +
',maximum-scale=' + _scale;
document.head.appendChild(oMeta); //把meta标签添加到head里面
})();
通过JavaScript把所有的目标屏幕宽度设置成一样的,计算出当前的屏幕宽度与我们所需要设定的屏幕宽度的比例,达到设备的适配。通过viewport进行适配,会出现先前提到的问题,就是在图片选取上要注意,图片过小会导致图的失真。
有一点需要注意,这种适配方法,在QQ内置浏览器中布局会错乱,出现很大的适配问题,如果不考虑QQ内置浏览器的话可以考虑使用这种方案,但是不太推荐。
利用 rem 适配
然而最常见的适配方法也就是使用rem来进行适配,很多小伙伴可能对于em和rem有些混淆,傻傻的分不清楚。
em:是根据父节点的字体大小进行计算的单位。
rem: r 代表根(HTML),知道r代表HTML后就可以明确的知道rem是通过HTML的字体大小进行计算的单位。
(function() {
// 获取到HTML
var oHtml = document.documentElement;
// 获取到移动设备的html的外围宽度,如果给HTML设置宽度会印象结果
_hWidth = oHtml.getBoundingClientRect().width;
// 获取到移动设备的视口的宽度,推荐使用
_Width = oHtml.clientWidth;
// 这里的16是拟定值,可以随意设置,最好能与你测试的设备宽度能整除,方便计算
oHtml.style.fontSize = _Width / 16 + 'px';
})();
改动css
#box {
width:100%;
}
#box:after {
content:'';
display:block;
clear:both;
}
#box div {
width:4rem;
height:4rem;
float:left;
font-size:36px;
line-height:4rem;
text-align:center;
color:white;
}
#box div:nth-child(1){
background:red;
}
#box div:nth-child(2){
background:blue;
}
#box div:nth-child(3){
background:green;
}
#box div:nth-child(4){
background:hotpink;
}
既然已经知道两者的区别,那么在实际开发过程中应该如何使用rem完成适配,上面的css代码中,rem又是怎么计算得出来的呢?
公式:元素所需设置的rem值=设计图测量的值/(屏幕的宽度/N),这里的N就是在JavaScript计算的时候除以的那个16。其原理是把屏幕平均分成了N份,并把一份的值赋值给了rem,也就是html根元素的字体大小。
我也去看了一下如某宝、某东的适配方案,他们同样使用的是rem进行适配的,但是与他们在rem赋值的做了判断,当屏幕大于750px就将屏幕宽度锁死,固定在750px使rem成为一个固定的值。这样当屏幕过大的时候,页面内容不会变的特别大。
(function() {
// 获取到HTML
var oHtml = document.documentElement;
// 获取到移动设备的html的外围宽度,如果给HTML设置宽度会印象结果
_hWidth = oHtml.getBoundingClientRect().width;
// 获取到移动设备的视口的宽度,推荐使用
_Width = oHtml.clientWidth;
_Width = _Width>=750?750:_Width;
// 这里的16是拟定值,可以随意设置,最好能与你测试的设备宽度能整除,方便计算
oHtml.style.fontSize = _Width / 16 + 'px';
})();
很多大厂都是采用的rem的这种适配方案,大家可以自行Google一下,大厂是如何处理的。理论上是差不多的,可能就是在用法以及对于rem计算的处理有些不同而已。不管如何处理只要懂得这个道理就好了。
随着设备的不同所要应用的事件也就会有所不同,然而在移动的应用onclick的时候是可以兼容的,会存在一些小问题,所以针对移动端,推出了移动端专用的事件,那么今天就具体和大家说一下,移动端的事件的一些问题,以及在解决这些问题的时候引发出的另一些问题。
现在会想起最初做移动端的时候,是使用onclick事件去完成一些操作,虽然移动端能够完成onclick的一些操作,还是会存在一些问题。
Click事件在移动端开发中会有300ms的延迟,因为在移动端早期,浏览器系统有放大缩小功能,用户在屏幕上点击两次以后,系统会触发放大或者缩小的功能,因此系统做了一个处理,当触摸一次后,在300ms以后有没有进行二次触摸,如果存在二次触摸,说明就触发了放大或缩小功能,否则的话只是单单执行click事件。因此当click时候,所有用户必须等300ms后才会触发click事件。所以当在移动端使用click事件的时候,会感觉有300ms的延迟。
移动端主要分为三个比较重要的事件,也是经常用的事件:
touchStart :手指按下
touchMove :手指移动
touchEnd :手指离开
移动端事件对象
移动端的事件对象与web端中的事件对象有些不太一样,web端我们在对页面进行操作的时候大多数都是依赖于鼠标,但是移动端是依赖于屏幕的,通过手指的触摸屏幕,给用户反馈,鼠标只能有一个,但是手机却又很多(●'◡'●)
移动端的事件对象存在于事件函数中:
例子:
var oDiv = document.getElementById('div');
oDiv.addEventListener('touchstart',function(ev){
console.log(ev)
})
事件对象属性:
属性 | 说名 |
---|---|
touches | 当前位于屏幕上的所有手指的一个列表 |
targetTouches | 位于当前DOM元素上的一个手指的一个列表 |
changedTouches | 涉及当前事件的手指的一个列表 |
大家可以通过上面的代码输出一下ev(事件对象),在控制台查看一下移动端都包含哪些东西。
除了上述事件,有个特殊事件再说一下orientationChange这个事件是苹果公司为safari中添加的。以便开发人员能够确定用户何时将设备由横向查看切换为纵向查看模式。在设备旋转的时候,会触发这个事件。
window.addEventListener("orientationchange", () => {
alert(window.orientation);
}, false);
orientation media query在ios3.2+和安卓2.0+上还有其他浏览器上有效。有些设备并没有提供orientationchange事件,但不触发窗口的resize事件。并且media queries也不支持的情况下,我们该怎么办呢?可以用resize事件来判断。用innerWidth,innerHeight,可以检索得到屏幕大小。依据宽和高的大小比较判断,宽小于高为竖屏,宽大与高就是横屏。就现在的移动端发展而言已经又大多数移动设备已经支持这个事件了。
移动端开发注意事项
在移动端开发的过程中,浏览器的模拟器有时可能会不支持on的方法绑定事件,所以一般要用事件绑定的方式给元素绑定事件。
var oDiv = document.getElementById('div');
oDiv.addEventListener('touchstart',(ev) => {
console.log(ev)
})
移动端开发有一个很大的坑,层级为了这个坑也是翻山越岭。这个大坑就是事件点透,最初看到这个名词的时候也是一脸的懵逼,不知道怎么回事。
什么是事件点透?当上层元素发生点击的时候,下层元素也有点击特性,在大约300ms后,如果上层元素消失或者隐藏,目标点会“漂移”到下层元素身上,触发点击事件。
解决方法:
1.下层不要使用有点击(焦点)特性的元素。
2.阻止document的默认行为
以上是关于前端 | 移动Web深度剖析(下篇)的主要内容,如果未能解决你的问题,请参考以下文章