整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML5移动应用开发踩过的那些坑

从移动平台崛起以来,HTML5移动应用开发迅速变成了热门话题,开发者们被各种开发HTML5移动应用的方法搞得晕头转向,今天请到了金山云基础架构部研发负责人柴春燕给大家分享如何避免HTML5移动应用最容易踩的那些坑。

柴春燕--

微软社区精英计划博客组负责人,HTML5研究小组成员,擅长HTML5及移动应用开发;

具有多年Web开发经验,曾参与开发微软Visual Studio 2010中文学习平台,基于SaaS模式的E-Learning系统;

曾负责当当网Web前端开发及移动应用开发,担任百度音乐高级研发工程师;

目前就职于金山云,初期负责金山云前端架构,现任基础架构部研发经理。

01/移动应用中HTML5的新特性

工欲善其事,必先利其器。我比较推崇的学习技术的方式,是先整体了解,然后结合实际需求,再做针对性的学习。整体了解的方式,比较建议是直接看官网的API文档,这里可以推荐几个网站: http://www.w3school.com.cn/html5/index.asp, https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/HTML5, http://www.html5rocks.com, http://caniuse.com/

其中,特别说明下http://caniuse.com/,通过这个网站,我们可以非常快速的查询到你所想使用的html5的特性在各个浏览器,包括不同终端的浏览器的兼容性情况。

HTML5 在移动应用开发上面能够利用的特性主要有:

1. form input type

表单是我们在开发中经常会遇到的,如果按照传统的方式,要介入jquery validate或者自己写正则进行判断,但是其实html5的form表单新增的input type属性,能够快速帮我们实现所需要的功能。

2. video & audio

移动浏览器是不支持flash的,在一些微信专题活动中,经常会看到嵌入音频,那么audio标签就是比较适合的应用场景,html5中audio提供的api attr还是比较全面的。

视频格式一般有mp4和webm两种格式,在使用的时候,一般建议同时生成两种,根据浏览器兼容性,进行相应的选择。音频audio,一般会同时制作mp3 ogg格式。

3. storage

关于web storage,大家可以参考我之前分享的一篇内容:

http://www.chaichunyan.com/topics/html5-training/5.html5_storage/#/

重点是localstorage,尤其是我们在做移动应用的性能优化时,localstorage能够发挥很大的作用。

学习的时候,建议大家带着问题去学习,比方说“localstorage最大的存储容量是多少?”“有没有有效期?”“cookie是有域的概念的,那么localstorage呢?”

4. css3

html5其实更多的是一个web标准,这个标准里边,包含了html、JavaScript api、css。css3是我们在移动应用中要重点学习和掌握的。

1.选择器

2.自定义字体

3.多栏布局

4.文字,容器阴影

5.圆角

6.渐变效果

7.动画 ...

大家可以通过下面一个例子有一个直观的印象:

http://www.chaichunyan.com/topics/html5-training/7.css3_summary/demos/index.html

之前很多我们需要通过js或者切图实现的效果,在移动端,就可以直接通过css3实现。

这里特别强调下关于布局,css3弹性布局,希望大家能够仔细去了解,我在面试时候,必问的一道题,当然,面试只是手段,更重要的是希望能够学以致用,真正在实际工作中发挥作用。

flexbox布局的兼容性,弹性盒模型实现的原理,这些我们在做移动终端调试时候,如果只是靠反复试错,那么效率是非常低的。

了解了html5的特性,开发者就会在移动应用上一展身手了。

02/HTML5移动应用中踩过的那些坑

1.布局

移动浏览器访问的web站点,后面称为mobile webapp哈(泛指移动终端浏览器访问的web站点),能不能使用传统的流式布局?答案是可以,但是要慎用。

mobile webapp对css3的弹性布局支持还是比较给力的,iOS Safari还好,但是Android的碎片化非常严重,尤其是Android上面各种第三方浏览器会做各种各样的定制化,使用flexbox比float能够减少你在布局调试上的时间,而且兼容性有保证。

2.图片适配

这里边要提供一个概念,是屏幕分辨率和物理分辨率,为什么我们使用ios看到的图片清晰度那么高,原因是普通的手机屏幕,一点显示一个像素,但是iphone4s 以后是一个点四个像素。

那按照320的设计稿切出来的图片,在iphone上面显示肯定是有锯齿的。

处理方法可以参见我之前分享的一篇文章:图片的适配与清晰度

http://blog.csdn.net/spring21st/article/details/7513906

3.字体

我把字体的处理分为两类,一种是艺术字体、icon,另一种是我们在页面中的字体。

移动终端对网络的要求是比较高的,我们要尽可能减少网络请求,图片是非常大的网络开销,当然,我们可以用合并图片的方式减少请求数,但是请求量变大了。

css3支持web fonts,所以,我们可以引入字体文件,而不是所有的字体都是通过切图的方式来实现。对于icon,一种方式是base64处理,但是现在更常见的做法,是转换成矢量字体。

这里推荐一个网站:font awesome http://fortawesome.github.io/Font-Awesome/icon/css3/

这里边涵盖了大部分我们会用到的图标,当然,公司有精力和人力的情况下,建议可以维护自己的矢量字体库。

4.横竖屏

我们可以通过css 的media query 判断横竖屏。

但是这种只能控制样式展现,当我们需要监听横竖屏变化的时候,就只能通过js监听window.onorientationchange事件的方式实现。

但是,下面这种情况会让你很无语:

那我们推荐下面这种实现方案:

相比较pc web,mobile webapp的调试更复杂,而且未知的问题更多,遇到问题,我们要有耐心去跟踪定位,就像之前我们遇到iscroll性能问题、fast-click穿透的问题,都是一点一点排查处理的。

03/混合应用(Hybrid)的注意事项

现在“快速迭代,敏捷开发,低成本上线“基本上是每家公司都追求的目标,混合应用就是在这种场景下应运而生。

Hybrid App优点众多,Web前端工程师0成本介入,不依赖版本的实时更新,快速实现跨平台需求,等等。但是,我对混合的看法是,根据实际情况合理使用,因地制宜。

那么什么样的场景适合混合应用开发?

1. 快速原型,验证产品功能。我们之前开发过一个app,Android和iOS提供宿主环境,webview展现内容都是通过html5实现的,半个月就开发上线了,较之传统应用开发人员成本和时间成本都缩短很多。

2. 内容类的应用,比如csdn的app,就是采用hbuilder混合方案实现的,对性能要求没有那么高。

在考虑hybird的时候,要避免以下几个误区:

(1)为了HTML 5而Hybrid App

html5只是技术实现手段而已,要根据公司的实际业务场景,以及人员配比,综合考虑,不能因为react native比较火,就必须要在公司推行这种实现方案,我觉得为技术而技术是不可取的。

(2)忽略移动应用中的关键因素

mobile webapp本质上还是基于PC的一种开发模式,开发者使用PC浏览器模拟App中的webview进行调试。PC浏览器与手机webview的区别是巨大的,包括能支配的CPU资源,最大占有的内存,运行的网络环境,click和touch事件的区别,浏览器对CSS/JS的解析和对事件处理等等。

app工程师考虑比较多的内存的问题,这些在web开发时候是很少考虑的。另外,就是网络环境方面,虽然现在3g、4g覆盖率越来越高,但是移动终端的访问和pc还是有很大差距,wifi和蜂窝网络的切换,基站变化等诸多因素都会导致网络间歇性断开,web开发对于这种不稳定网络环境问题的处理上都有所欠缺。

(3)交互体验一致性

ios和Android的交互设计是两套规范,虽然有相似的地方,但是从操作习惯上,就已经决定了,我们想用一套交互设计,适配两个平台是很难的,包括包括视觉风格,界面切换,操作习惯等。

Hybrid App方案是一把双刃剑,一方面它平衡了Native App和Web页面的优缺点,一定程度上解决了Native App开发过程中迭代慢,版本依赖,Native开发资源不足的问题,但另一个方面过度依赖Hybrid方案会造成Web前端开发成本快速上升,甚至造成App整体体验下降,甚至造成功能缺失。

回到最开始那句话”不要为了Hybrid而Hybrid“,根据实际场景,控制好方案中native和web的边界。

04/Q&A

Q1:关于响应式开发中对于手机屏幕高度的解决有没有什么好的解决方案?

响应式开发本质上是移动设计优先的一种开发方式,我没太明白对于手机屏幕高度的解决,具体的问题是什么样的,原则上高度是不需要做处理的,除非是你对首屏有要求。关于响应式开发,可以看看我这篇文章http://www.chaichunyan.com/index.php/2016/03/03/html5-wrd/

Q2:对首屏有要求的情况, 除了判断高度还有没有其他好的解决方案?如果是flex布局可以解决这个问题吗?

问题的根本是获取首屏的高度,(1)如果你是后端渲染的话,可以获取机型和浏览器版本,拿到屏幕分辨率做适配 (2)根据屏幕宽度做适配,但是做不到完全绝对的首屏自适应,如果有更好的方案,我再跟大家分享。

Q3:hybrid开发中,h5页面太多的话,会不会影响ios发布?

之前有ios对phonegap这种跨平台的应用审核是不通过,不过现在放开这个限制了。h5页面过多,会影响应用的性能和体验,建议可以把h5打包放到ipk里边,但是要做好静态资源的版本管理。

Q4:css3 弹性布局中, 由于android碎片化严重的问题, 能不能有好的案例指导? 我们要求支持到android4以上版本。

真的要善用文档和工具, http://caniuse.com/#search=flex, 我分享时候提到的这个网站,明确说明了flex兼容性。

如果是Android4.4以上机型,基本上可以放心使用,注意的地方有两个:1. 要记得写各个浏览器的css前缀 2. flex里边可以嵌套flex.

Q5:hybird开发过程中, 原生代码登录权限问题,h5部分的页面,如何共享登录相关信息?

这要看你实现的方案,(1)嵌套静态的h5页面,那么需要native打开webview的时候,使用js briage调用页面js的方法,写入用户信息,实现登录共享 (2)如果打开的是动态渲染的页面(如php输出的页面),那么可以在请求的url中携带用户token,php通过query string判断验证,这个是native和webview数据交互的问题。

Q6:h5动画在部分安卓webview中有时候会出现卡顿,这种情况改怎么优化呢?

1. 可以做简单的测试,看看浏览器支持的情况,如果浏览器支持不够好,那么可能要做降级处理。

2. 减少动画效果,因为动画是要使用gpu渲染的,原生app能够流畅,很大程度上是直接调用硬件处理的。

优化的方案我这边基本上是降级处理,Android低版本不支持的话,就使用基本动画,比方不会使用3D翻转。因为h5毕竟受限于webview环境,像jquery 和 zepto都提供对机型和浏览器的判断。

Q7:在移动端浏览器上能支持h5离线存储的性能吗?

No problem.我们在实际项目中,优化前端性能,曾经用localstorage做静态资源的版本管理和存储。

更多技术干货关注公众号“极牛”。

前面学习了HTML5的基础新元素,接下来小编将继续分享HTML5必学的知识点--HTML5新表单

在开始之前,先来了解一下HTML5的声明,<!doctype html>,通过HTML的声明,体现W3C故意弱化HTML的版本,但是小标要说明下版本不更新,不等于内容不更新,而是W3C希望HTML5是融合版本。

关于HTML的发展历史, HTML的规范不严格一直以来就是前端开发人员头疼的地方, 元素定义大小写不敏感。

直到XHTML 1.0的出现 - 前端开发人员拥抱,因为此时的HTML只允许小写

XHTML 2.0版本出现后 - 前端开发人员重新回到HTML, 推翻了之前很多习惯

HTML 4版本出现之后 - 比较好的版本

HTML 5版本出现 - 经历8年后,终于在2014年10月底发布

HTML5的特点:移动端浏览器相比PC端浏览器对H5的支持更好,这要感谢苹果公司 - 乔布斯

小编提醒大家:目前网上所谓的H5,并不是指现在所学HTML5技术,HTML5的新特性内容不多,与JS(难)配合使用

那么实际工作中使用多不多?其实实际上来说,相对并不多

其实就是在为将来学习 - HTML5将来一定是主流。

*******华丽分割线*******

接下来开始学习,HTML5必学知识点—新表单,主要从4个方面入手:新类型、新元素、新属性、新验证

首先是INPUT新类型,新增了以下类型:

1.email类型 - 判断字符串中是否包含"@"符号,注意的是不能以"@"开始、不能以"@"结束

2.搜索类型 - search

3.URL类型 - 判断字符串中是否包含"http:",注意的是以"http:"开始,验证通过,以"http:"结束,验证通过

4.电话号码类型 - tel,注意的是只有在手机端浏览器访问时有效果

5.数字类型 - number,需要注意的是允许输入非数字内容,但是不允许提交,在设置min和max时,允许输入范围外的值,不允许提交;这个类型有一些属性: min - 设置数字的最小值;max - 设置数字的最大值;step - 设置步长,每次增加或减小的量值

6.范围类型 - range,效果就是滑动条,属性:min - 最小值、max - 最大值、step - 步长、value - 当前值

7.颜色类型 - color

8.日期类型 - date,日期格式 - yyyy/MM/dd

9周、月份类型 (实际很少使用)

10周 - week(实际很少使用)

11月份 - month(实际很少使用)

第二部分是表单新元素

1.<datalist>元素,用法:需要配合input元素使用,在input元素中定义list属性(值为datalist元素的id值),好处就是数据与结构的分离

2.<progress>元素,就是实现一个进度条,属性有:max - 设置进度条的最大值、value - 设置进度条当前的值

3. <meter>元素,用法和<progress>元素类似,作用 - 刻度,属性包括:min和max - 设置最小值和最大值、 value - 表示当前值,high和low - 设置预警值(举个常见的例子,当你手机的电量小于10%时候,一般会显示红色的一小段进度)

4.<output>元素,和<input> 输入框正好相反,<output>是输出框,属性:for指定要输出的元素进行关联(实际开发中,很少使用)

第三部分是表单新属性

1.placeholder属性:就是实现input输入框的默认提示信息,相比value属性值更好用。这个在实际开发过程中非常常见

2.autofocus属性:就是自动获取焦点、用法有点不同,它不是key=vlaue的形式,而是直接只定义属性名(没有属性值)

3.multiple属性:就是允许输入框输入多个值,用法和autofocus一样只定义属性名(没有属性值)

4.form属性(实际开发中用到不多):就是表单元素定义在表单之外,用法 - 值是相关表单的id属性值

第四部分是表单新验证(这是一个难点,也是重点)

1.验证属性:

required属性即:验证是否为空?返回false,表示当前元素值为空, 返回true,表示当前元素值不为空

pattern属性即:验证正则表达式,定义正则表达式时,不能添加"//", 正则表达式不能验证是否为空

min和max属性即:验证最小值和最大值 ,只和number类型的input元素配置使用

minlength和maxlength属性即:验证最小长度和最大长度,minlength - 验证最小长度,maxlength - 限制最大长度(输入内容的长度不能大于maxlength的值)

validity属性即:HTML5提供表单验证的接口,通过该属性得到validityState对象,该对象提供一系列的有效状态, 有效状态可用于表单验证,得到validatyState对象,elem.validaty - 得到该对象

2.有效状态

valid - 返回Boolean,表示验证是否通过,true - 表示验证通过, false - 表示验证失败,

valueMissing - 表示值是否为空,返回值true - 表示元素值为空(错误)、false - 表示元素值不为空(正确) 注意该状态配合required属性使用

typeMismatch - 表示元素类型是否匹配,返回值true - 表示元素类型不匹配、false - 表示元素类型匹配、 该状态配合email、url、number等使用

patternMismatch - 表示正则表达式是否匹配、返回值true - 表示正则表达式不匹配、false - 表示正则表达式匹配,该状态配合pattern属性使用

tooLong - 表示元素内容长度是否过长,返回值true - 表示元素内容长度过长,false - 表示元素内容长度不长,该状态配合maxlength属性使用

maxlength属性 - 限制属性,tooLong可能不会出现(完整性)

rangeUnderflow - 表示元素值是否小于min值,返回值true - 表示元素值小于min的值,false - 表示元素值不小于min的值 该状态配合min属性使用

stepMismatch - 表示元素值与step值是否不符,返回值true - 表示元素值与step值不符,false - 表示元素值与step值相符 该状态配合step属性使用

customError - 自定义错误,配合setCustomValidity()方法使用,作用就是替换之前的判断表达式,自定义错误提示信息setCustomValidity(自定义错误信息),一旦调用该方法,默认认为就是错的,上述所有的有效状态返回错误值 验证正确时,调用该方法,将错误信息置为空

增type类型:

Type=“email” 限制用户必须输入email类型Type=“url” 限制用户必须输入url类型,“http://”Type=“range” 产生一个滑动条表单Type=“number” 产生一个数字意义表单Type=“search” 产生一个搜索意义的表单Type=“color” 生成一个颜色选择的表单Type=“time” 限制用户必须输入时间类型Type=“month” 限制用户必须输入月类型Type=“week” 限制用户必须输入周类型Type=“datetime-local” 选取本地时间Type=”date” 限制用户必须输入日类型

表单输出框:

<output></output>

<form action="" oninput="x.value=parseInt(a.value)+parseInt(b.value)">

<input id="a" type="range" min="0" max="100">100+

<input id="b" type="text" value="50">=

<output name="x" for="a b"></output>

</form>

datalist 下拉菜单框: 必须和list属性结合使用。做提示信息。

<input type="url" list="url_list" name="link" />

<datalist  id="url_list"> 
		    <option label="W3School" value="http://www.W3School.com.cn" /> 
		    <option label="Google" value="http://www.google.com" /> 
		    <option label="Microsoft" value="http://www.microsoft.com" /> 
</datalist>

新增表单属性:

required 监测是否为空。min 最小max 最大step 步幅 确定一个法定值。0 3 6 9 (不能写负值)list 必须结合datalist标签,绑定datalist id名称。 autocomplete 是否自动提示信息 属性值 on 打开 ;off 关闭 (是否有缓存)注:默认值是on ;

placeholder 文本框的提示信息 autofocus 自动聚焦。一个页面只能由一个。pattern 后面的属性值是一个正则表达式。(js)novalidate 取消验证multiple 选择(上传)多个