[ 遇坑总结 ] 记一次移动端开发(1)

最近一段时间做了一个移动端的网页导航工具,也加了一些个人比较常用的小工具,比如翻译、转盘、进制转换等等,如果大家感兴趣可以去看看,GitHub

第一次做移动端,其实也是第一次完全按照自己的想法做东西,遇到了很多坑,我将会用两篇文章来总结一下遇到的那些小故事

1. 异常丰富的标签

移动端相对于PC端有一个好处,就是没有古老的 IE ,而且手机端的浏览器相对于电脑的还是更集中一些,基本只有 safari 稍微矫情一点,但是好在苹果的系统更新还是非常良心的,四五年前的手机都会更新最新系统,而这两年的 safari 都蛮好用的,没有太多需要单独适配的。

但是移动端也有一个巨大的问题,那就是屏幕尺寸,在小米 MIX 将全面屏带入市场后,所有厂商都开始了全面屏,屏幕尺寸可谓是五花八门,所以这篇文章首先来说说为了各种屏幕,要考虑的问题

通用浏览器的可视区域配置
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>

这算是所有移动端开发必须的一个 标签了,下面是其中的属性所代表的含义

width   正整数或device-width    定义视口的宽度,单位为像素
height  正整数或device-height   定义视口的高度,单位为像素
initial-scale   [0.0-10.0]  定义初始缩放值
minimum-scale   [0.0-10.0]  定义缩小最小比例,它必须小于或等于maximum-scale设置
maximum-scale   [0.0-10.0]  定义放大最大比例,它必须大于或等于minimum-scale设置
user-scalable   yes/no  定义是否允许用户手动缩放页面,默认值yes

实际上这里有了 maximum-scaleminimum-scale,可以省略 usr-scalable

iOS 设备的一些配置
WebApp全屏模式
  <meta name="apple-mobile-web-app-capable" content="yes"/>
工具栏颜色
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
从主屏打开以全屏模式打开
	<meta name="apple-touch-fullscreen" content="yes" />
添加到主屏时图片和标题
	<link href="图片地址" sizes="114x114" rel="apple-touch-icon-precomposed"/>
	<meta name="apple-mobile-web-app-title" content="标题"/>

iOS设备用到的基本就这些了,下面详细说一下这些属性的取值

全屏模式       yes/no   表示是否全屏
工具栏颜色     black(黑色);black-translucent(灰色半透明);deault(默认白色,夜间模式?)

后两个没啥说的了,就放过吧

QQ浏览器(X5)内核
设置屏幕方向
	<meta name="x5-orientation" content="portrait|landscape"/>     
设置全屏
	<meta name="x5-fullscreen" content="true"/>
UC浏览器独有
设置屏幕方向
	<meta name="screen-orientation" content="portrait|landscape"/>
设置全屏
	<meta name="full-screen" content="true"/>
缩放不出现滚动条
	<meta name="viewport" content="uc-fitscreen=no|yes"/>
夜间模式
	<meta name="nightmode" content="enable|disable"/>
节流模式强制显示图片
	<meta name="imagemode" content="force"/>

最后一个节流模式显示图片的,应该可以应用到其他浏览器

对于电话邮箱的控制
关闭电话自动识别:
<meta name="format-detection" content="telephone=no"/>
开启拨打电话/发送短信功能
<a href="tel:123456">立即拨打电话</a>    
<a href="sms:123456">立即发送短信</a>
如果同样也需要禁止自动识别邮箱,可以在原来的基础上增加“email=no”。
<meta name="format-detection" content="telephone=no,email=no"/>
开启自动识别邮箱
<a href="mailto:example@163.com">给我们发邮件</a>

这算是移动端调用本机应用特有的 API 了,虽然用的不多,但是一般来说一个健壮的项目还是会使用到的

还有一些其他的 <meta> 标签,我并没有用到的,但是可能还很好用的,大家可以去网上搜查一番,这里列举的都是比较常用的,或者说几乎一定会使用到的一些。

2. 强大的flex布局和有趣的 vw、rem单位

介于移动端屏幕尺寸的五花八门,平常的布局,再加 px 的单位已经很难完成一个稍微有点花样的界面了,所以这次使用了较为灵活的 flex 布局,用到了 vwvhrem单位。

flex布局

虽然我还没有面试过,但是看好多笔试面试题都会提到 flex 布局,甚至是深入考察。毕竟这玩意实在是太强大了

关于 flex 本身,我不过多赘述了,网上这方面的文章实在是太多了,在这里我推荐一个网站,可以很直观的看到使用flex的各种属性的效果 CSS属性可视化文档-flexbox

我在这里说一些我们可能经常用到的小栗子

1. 圣杯布局

什么是圣杯布局呢,这里给一个例子

*pic-圣杯布局动图*

也就是左右两侧的宽度不受页面缩放的影响,中间的部分会因页面缩放而变化,贴一下代码

<!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>圣杯布局</title>
	<style>
		body{
			display: flex;							/* 对父元素使用 flex 布局 */
			justify-content: center;		/* 居中现实,实际上这个可以不用,但是如果 .content 有最大宽度,则有必要 */
		}
																	/* flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为 0 1 auto。后两个属性可选。 */
		.left{
			flex: 0 0 200px;						/* 左侧不允许放大、缩小、固定200px */
			height: 800px;
			background-color: #fba;
		}
		.right{
			flex: 0 0 200px;						/* 右侧不允许放大、缩小、固定200px */
			height: 800px;
			background-color: #fab;
		}
		.content{
			flex: 1;										/* 相当于设置 flex-grow,这里设为 1 表示占据剩余所有空间*/
			height: 800px;
			background-color: #abf;
		}
	</style>
</head>
<body>
	<div class="left"></div>
	<div class="content"></div>
	<div class="right"></div>
</body>
</html>

这可能是最简陋的圣杯布局了,但是也是非常容易理解原理的一个。

原理就是,父元素设置其子元素为 flex 布局,默认横排,即主轴是横着的,然后让子元素根据主轴居中。在子元素,左右两个都设置为宽度固定,中间的设置为宽度根据剩余控件自由缩放。

这里需要注意的是 flex 属性,既然它是 flex-grow, flex-shrinkflex-basis的简写,那么对于 .content 不分开写呢,这是因为如果分开写,浏览器会根据上下文推算相关值,对于喜欢追求极致性能的人,还是不要分开写了。

2. 垂直居中

垂直居中算是我们非常常用的了,在以前,可能需要 absolute将子元素死死固定在计算好的地方,也可能对行内元素用 line-height 巧妙的居中起来,甚至是用父元素的 padding将子元素卡在那个动弹不得的位置 ……

垂直居中的方法实在是太多了,有人总结了上十种,我就不一一列举了,毕竟我也列不出那么多,哈哈哈。这篇文章就介绍一下我最喜欢的 flex 居中,实现起来简直不要再简单,而且巨灵活

*pic-flex垂直居中*

下面贴一下代码

<!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>居中</title>
	<style>
		body{
			height: 100vh;							/* 高度为可试区域的高度 */
			display: flex;							/* 使用 flex 布局 */
			justify-content: center;		/* 根据主轴居中显示 */
			align-items: center;				/* 根据交叉轴居中显示 */
		}
		.content{
			width: 300px ;
			height: 200px;
			background-color: #abf;
		}
	</style>
</head>
<body>
	<div class="content"></div>
</body>
</html>

最主要的就是 body 上设置的 align-items ,它表示交叉轴上居中,这个例子中,主轴是横向的(默认),交叉轴便是竖向的。

是不是很简单,在实际中基本只需要两行就可以搞定了,简直不要太爽

3. flex不能做什么?

我的经验不多,确实说不出几个flex不能做什么的例子,但是有一个确实很难搞,那就是瀑布流效果

  1. 瀑布流效果

因为 flex 的轴是直的,它不能折起来,所以瀑布流那种参差不齐的样式就是为难胖虎的感觉了。

  1. 子元素脱离文档流

这个子元素是设置了 felx 的元素的直接子元素,它是无视 absolutefixed的,当然也不是没有办法解决,我们可以给子元素再嵌套一个子元素,这个孙子元素设置了 absolutefixed就可以脱离文档流了,但问题是会多一层 DOM,所以遇到这种问题,就需要一定的取舍喽

vw、vh、rem

细心的朋友可能看到了,我在上面用 flex 做居中的例子中就用到了 vh,这里先简单介绍一下这三个单位

vw   网页可视区域宽度
vh   网页可视区域高度
rem  1 rem == html元素上font-size 大小

在刚开始我的那个小项目的时候,感觉 vh 简直太棒了,那时候还是一直用电脑上的 chrome 调试器的,直到加了一个 <input> ,在手机上调试的时候才知道有多糟糕,下面就给大家大概演示下我当时的情况

*pic-手机端键盘弹出影响页面布局*

可以看到,在软键盘弹出来的时候,vh 的大小居然也变小了,而且屏幕上多了莫名其妙的一个横条,当然这个可能是浏览器的问题,因为在其他浏览器就没有这个。还有就是浏览器默认顶部有一个搜索框,这个是会根据滑动进行变化的(有的浏览器是底部工具栏会动,如夸克),在实际应用中,那会是一个很糟糕的情况,只要页面一滑动,就感觉会有卡跳。

最终,我将很多单位都进行了更改,能用vw,就用vw,或者直接用 rem 替代。但是有些地方只能用vh,我也想了一个办法,固定vh ,来解决这个问题。rem 虽然也是一个很好的办法,但是如果手机分辨率跨度大,比如好几年前的iphone5,再到现在主流的1080P的屏幕,如果设置一个固定的rem,在 iPhone5 上会有巨大号的字体,而在现在的手机上,可能又比较小,这里也借鉴了一下小米网移动端的官网,给不同手机分辨率不同的rem,下面是我使用vh的rem的一个小技巧

固定 vh

固定vh,我的思路是在 CSS 中定义一个变量,存储页面高度,也就是 vh的大小,然后在页面刚加载,用 JS 获取页面的高度,并赋值给 CSS 变量,这样,就算是弹出软键盘,也不会影响vh了。下面贴一下代码

// JS
var screenHeight = $(window).height();
document.documentElement.style.setProperty("--origin_vh", screenHeight + "px");
// CSS
:root {
  --origin_vh: 100vh;
  /* 页面刚加载高度,即屏幕高度;默认100vh可以减少修改 vh 后页面抖动 */
}

这里 --origin-vh 就是一个固定的 vh ,在页面正常加载后,就会有一个很好的体验。但是这样也会有一个问题,那就是如果我们的项目需要改变页面尺寸,比如需要兼容横屏显示,那么只是这么做就不够了,那时候就要在需要改变页面尺寸的时候,重新计算 --origin-vh ,并在设备回正后再改变一次,这样做的时候最好再加一个 transition,可以看以来稍微平滑一些。

自适应rem

前面说过了,rem 的计算,我借鉴了小米移动端官网的计算,那么咱们就看看他们是怎么做的

*pic-小米商城 rem 解决*

可以看到,在页面宽度在 720px 以上的时候,rem 为100px,在720px 以下会不断变化,简单计算后,发现,rem = screenWidth * 0.138889

这么一来,那问题就简单多了,只要在页面初始化的时候给 <html> 元素的font-size设置一个计算好的值就可以了,同样,这样做只会生效一次,那么可以在页面尺寸发生变化后,再计算一次。

下面贴一下代码

	var screenWidth = $(window).width();
	if (screenWidth < 720) {
		$('html').css('font-size', screenWidth * 0.138889);
	} else {
		$('html').css('font-size', 100);
	}

我是为了简单,就用了 jQuery,实际上,这个更应该直接在 <head> 中运行,这样就可以消除由于 rem 改变,导致页面加载后使得用到rem的元素发生跳变。

上半部分就写到这里,还有一些实践中的小技巧、小坑我将在下一篇文章中总结 记一次移动端开发(2),有兴趣的朋友可以去看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值