为了账号安全,请及时绑定邮箱和手机立即绑定

简简单单的移动web开发基础知识讲解

前言

这篇文章是根据慕课网的课程——《hello,移动web》,虽然课程已经很久远了,但是细细读来还是能够get到很多的知识,下面进入正文。

移动开发中的像素(px)

首先,抛出一个问题:640x1136的图片,能不能在iPhone5上完全显示?毕竟iPhone5的分辨率是为640x1136的。空想无用,现在我们用下面一段代码进行测试一下

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Test</title>
    <style>
      #app {
        width: 640px;
        height: 1136px;
        background-color: green;
        color: #fff;
        font-size: 150px;
        text-align: center;
        font-family: "微软雅黑";
      }
    </style>
  </head>
  <body>
    <div id="app">
      hello Mobile
    </div>
  </body>
</html>

打开Chrome浏览器,模拟iPhone5手机进行查看,看到结果了吗?是不是很惊讶,盒子居然没有铺满全屏,而且在浏览器上显示的iPhone5尺寸是320px*568px,这到底是怎么回事?不用太惊讶,我们先捋一捋各种像素之间的关联马上就能明白。

物理像素与逻辑像素傻傻分不清楚?

首先,iPhone5的分辨率(640x1136)指的是物理像素,也可以说是设备无关像素,单位是dp或者pt,状态无法改变,厂家设置为多少就是多少;而我们开始使用的CSS样式中px代表的是逻辑像素,是浏览器使用的抽象单位,状态是可变的。这两种像素之间的关系就是由设备像素缩放比(dpr)连接起来的。下面来看一下它们之间的计算公式。

计算公式:1px = (dpr)² * dp

那么看到上面的公式,我们再来想一想,为什么iPhone5在浏览器显示的尺寸是320x568?那是因为在iPhone5中,dpr的值为2。可能大家还是有点懵,好了,下面我们再继续分析下。

在平面上:1px = (2)²xdp,那么在维度上就是:1px = 2xdp,这里我们需要搞清楚平面和维度 之间的关系。于是我们就能够得出0.5px = 1dp,则推理出320px = 640dp,568px = 1136dp。这样一步步推算下来,是不是非常简单?

关于DPR的种种

好了,默认上面的知识大家都理解了,下面我们来看看为什么iPhone5的DPR为2?

在手机上,有个叫PPI的东西,它代表的是手机设备屏幕每英寸的像素数量,即单位英寸内的像素密度。

每英寸的像素密度计算方式:PPI = 根号(1136²+640²),再除以4。为什么要除以4呢?因为iPhone5的屏幕尺寸为4英寸啊。然后根据这个公式就能够得出iPhone5的像素密度为:根号(1136²+640²)/4 = 326ppi

通过分析、推理可知,单位英寸内像素密度(PPI)越高,则物理像素数越高,于是图像就越清晰。

在图像越清晰的时候,可视度就越低,系统默认设置缩放比越大。比如,当你的电脑屏幕设备分辨率为1920x1200时,桌面的图标和文字会比较小(相对);当电脑屏幕设备分辨率为1280x720时,桌面的图标和文字会比较大(相对)。

谈到这个缩放比,界内有个标准图
image
Ldpi代表低像素密度;mdpi代表中像素密度;hdpi代表高像素密度;xhdpi代表超高像素密度。

最后一张图来总结上面的推算公式,其实非常好理解,只要你认认真真看两遍,亲自动手动脑整理一遍,一下子就明了。
image

Viewport相关知识

还是先抛出一个问题:一个PC的页面在移动设备上展示的效果是怎么样的?答案就是整个页面都铺满在手机上了(不过里面的文字和照片什么的全都变小了)!是不是非常的unimaginable?其实这就是在html文档中Viewport的神秘力量。

手机浏览器默认为我们做了两件事: 1、使页面渲染在一个980px(IOS)的布局viewport中;2、对页面进行缩放。

为什么手机浏览器在渲染一个页面时,要有Viewport?那是因为Viewport是手机浏览器虚拟出来的一个区域,目的是为了避免PC端的页面到了手机端可能会出现的布局错乱问题。

但是在真正的开发中,我们却不会去使用默认的980px的布局viewport,为什么不使用呢?原因如下:

  • 宽度不可控制,不同系统不同设备的默认值都可能不同;
  • 页面缩小版显示,交互不友好;
  • 链接不可点击;
  • 有缩放,缩放后又有滚动;
  • 最主要的是font-size为40px等于PC上12px同等物理大小,不规范

基于以上原因,我们可以通过meta标签去改变默认的viewport,欲知详情,往下翻即可。

Viewport中meta标签

设置Viewport中meta标签的默认语法为:
<meta name=”viewport” content=”name=value,name=value”>

name值一般有如下几种:

  • width:设置布局viewport的特定值(device-width)
  • initial-scale:设置页面的初始缩放
  • minimum-scale:最小缩放
  • maximum-scale:最大缩放
  • user-scalable:用户能否缩放

拿到页面默认的布局viewport值语法是:document.body.clientWidth

取得度量viewport值的语法是:window.innerWidth

那么问题来了,度量viewport到底是个啥玩意啊?其实我真的很晕,下面是我做的一些调查分析:
image
根据上面那副图我暂时分析出来的东东就是这样的:
document.body.clientHeight/Width的值默认取CSS样式中定义的元素高和宽,假如在meta标签中有对height和width定义,那么document.body.clientHeight/Width取得的值就是meta标签中定义的值,这就是一些布局viewport特性。

度量viewport我就很懵逼了,假如它也是和元素的宽高对应的话,那为啥window.innerHeight为622px而不是668px?!阿西八!

关于度量viewport这玩意还得和屏幕缩放比结合在一起探究探究,张鑫旭大大说的是:window.innerWidth/innerHeight指的是浏览器内部宽度/高度的大小 ,我们接着往后看。

继续探讨一下,如何将宽高为320x568的元素铺满整个iPhone5手机浏览器屏幕呢? 很简单,只要我们设置meta标签中的content=”width=320”即可,下面请看完整代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=320" />
    <title>Test</title>
    <style>
      body {
        margin: 0;
      }
      #app {
        width: 320px;
        height: 568px;
        background-color: green;
        color: #fff;
        text-align: center;
        font-family: "微软雅黑";
      }
    </style>
  </head>
  <body>
    <div id="app">
      hello Mobile
    </div>
  </body>
</html>

假如不出效果,那么记得多刷新下页面。

然而按照上面的写法,页面宽度根本无法适应所有手机浏览器屏幕,于是就有了一个非常神奇的属性:content=”width=device-width”。width=device-width这个属性值的含义就是布局viewport时刻等于我们的设备viewport。

接下来我们来看看屏幕缩放比这玩意,它的计算方式为:window.innerWidth/document.body.clientWidth

用文字表达就是:度量viewport/布局viewport = 屏幕的缩放比。

于是当我们控制缩放比的时候:
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0" />,就强制让度量viewport等于布局viewport了。

总结就是: 移动web最佳viewport设置为:布局viewport = 设备宽度 = 度量viewport

关于移动端开发,还有以下几个知识点需要好好学习

  • flexbox弹性盒子布局:这是我自己做的一些总结,看了还是不会的话过来打我啊;
  • rem单位:说到rem不得不先说一下em单位,em单位是根据父节点的font-size为相对单位;而rem是根据html的font-size为相对单位。因为rem的特性,从而使它成为了适配移动端页面的热门名词。只是不应该使用rem的是页面的字体大小,字体大小尽量为一个固定值为好;
  • vh和vw单位:vw 相对于视窗的宽度,视窗宽度是100vw;vh 相对于视窗的宽度,视窗宽度是100vh。更详细的内容请来张鑫旭大大的博客进行查阅。

移动端开发1px边框问题

这是retina屏幕下的问题,根本原因是因为:1px使用了2dp渲染。目前成熟的解决方案是使用缩放(scaleY(0.5)),下面贴核心代码

.folder li {
  position: relative;
  padding: 8px 0 8px 15px;
  color: #FFFFFF;
  cursor: pointer;
}
.folder li + li:before {
  position: absolute;
  top: -1px;
  left: 0;
  content: "";
  width: 100%;
  height: 1px;
  border-top: 1px solid #ddd;
  transform: scaleY(0.5);
}

移动端的单行文本溢出和多行文本溢出解决方式

不多说了,直接看代码

/*单行文本溢出*/
.inaline {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/*多行文本溢出*/
.intwoline {
  display: -webkit-box !important;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-all;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

移动端300ms的故事

移动web页面上的click事件响应都要慢上300ms。原因是在开始的时候移动设备访问的web页面都是PC上的页面,在默认的viewport(980px)的页面往往都是需要“双击”或“捏开”放大页面来看清页面。而正是为了确认用户是“双击”还是“单击”,safari浏览器需要个300ms的延迟来判断。而后来的iPhone也一直延用这样的设计,而借鉴成功iPhone的android也延用这样的设计。于是300ms就成为了一道规范。

如何解决300ms延迟的问题?
使用Tab事件代替click事件,其中的原理是:在touchstart、touchend时记录时间、手指的位置,在touchend时进行比较,如果手指位置为同一位置(或允许移动一个非常小的位移值)且时间间隔较短(一般认为是200ms),且过程中未曾触发过touchmove,即可认为触发了手持设备上的“click”,一般称它为“tap”

移动端Tap穿透的小bug

这个小bug是这样的,在手机端有个区域绑定了一个点击事件,事件上面有一个蒙层,当点击蒙层,蒙层消失的时候却触发下面那个区域的点击事件。

造成这个小bug的原因是因为移动端的300ms延迟特性,点击蒙层消失的那一瞬间,点击事件就被记录下来了,接着下层区域的点击事件被触发。

那么该如何解决这个问题呢?

  • 使用缓冲动画,过渡300ms的延迟;
  • 加入中间层dom元素,让中间层接受这个“穿透”事件,稍后这个中间层就隐藏。
  • “上下”都使用Tab事件,原理上解决tab穿透事件,但是不可避免原生标签的click事件。
  • 使用fastclick.js这个库

暂时就说到这里,课程后面的内容不做整理,因为自身对于移动开发的经验不足,看后面的视频也是迷迷糊糊的状态,应该和现在的大前端有一定的关系,毕竟如今的前端开发的趋势是基于数据驱动开发,而不是基于DOM开发。

点击查看更多内容
9人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
114
获赞与收藏
415

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消