基于html5的移动web页面搭建技术总结
1.技术要点
1.1面向不同尺寸的手机屏幕,页面布局适配问题。
网页的head里加入这条元标签,在iPhone的浏览器中页面将以原始大小显示,并不允许缩放。
width - viewport的宽度height - viewport的高度
initial-scale -初始的缩放比例
minimum-scale -允许用户缩放到的最小比例
maximum-scale -允许用户缩放到的最大比例
user-scalable -用户是否可以手动缩放
CSS3****的媒体查询media queries****语法:@media****:{ sRules }****取值:******:****指定设备名称。**
通过媒体查询可以为不同大小和尺寸的媒体定义不同的css,适合相应的设备显示。
以下代码实现了不同针对不同分辨率调整相应的文本,内容,元素的调整:
@media screen and (min-width:240px) { html,body,button,input,select,textarea { font-size: 9px } } @media screen and (min-width:320px) { html,body,button,input,select,textarea { font-size: 14px; } } @media screen and (min-width:380px) { html,body,button,input,select,textarea { font-size: 15px } } @media screen and (min-width:420px) { html,body,button,input,select,textarea { font-size: 16px } } @media screen and (min-width:450px) { html,body,button,input,select,textarea { font-size: 18px } } @media screen and (min-width:480px) { html,body,button,input,select,textarea { font-size: 19px } } @media screen and (min-width:540px) { html,body,button,input,select,textarea { font-size: 20.25px } } @media screen and (min-width:600px) { html,body,button,input,select,textarea { font-size: 22px } } @media screen and (min-width:640px) { html,body,button,input,select,textarea { font-size: 24px } } @media screen and (min-width:720px) { html,body,button,input,select,textarea { font-size: 28px } } @media screen and (min-width:800px) { html,body,button,input,select,textarea { font-size:30px } } @media screen and (min-width:880px) { html,body,button,input,select,textarea { font-size: 34px } } @media screen and (min-width:960px) { html,body,button,input,select,textarea { font-size: 38px } }
尽量避免px****布局,采用rem****布局**
PX****特点******
- IE无法调整那些使用px作为单位的字体大小;
2.国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位; - Firefox能够调整px和em,rem,但是96%以上的中国网民使用IE浏览器(或内核)。
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。(引自CSS2.0手册)
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。(引自CSS2.0手册)
任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为16px*62.5%=10px,这样12px=1.2em, 10px=1em,也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。
EM****特点******
- em的值并不是固定的;
- em会继承父级元素的字体大小。
所以我们在写CSS的时候,需要注意两点: - body选择器中声明Font-size=62.5%;
2.将你的原来的px数值除以10,然后换上em作为单位;
3.重新计算那些被放大的字体的em数值。避免字体大小的重复声明。
也就是避免1.2 * 1.2= 1.44的现象。比如说你在#content中声明了字体大小为1.2em,那么在声明p的字体大小时就只能是1em,而不是1.2em,因为此em非彼em,它因继承#content的字体高而变为了1em=12px。
**rem****特点******
rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。这个单位与em有什么区别呢?区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。
1.2视频声音更多灵活多媒体交互
视频
HTML5
元素同样拥有方法、属性和事件。其中的方法用于播放、暂停以及加载等。其中的属性(比如时长、音量等)可以被读取或设置。其中的DOM事件能够通知您,比方说,元素开始播放、已暂停,已停止,等等。
具体使用demo如下:
varmyVideo=document.getElementById("video1"); functionplayPause() { if(myVideo.paused) myVideo.play(); else myVideo.pause(); } functionmakeBig() { myVideo.width=560; } functionmakeSmall() { myVideo.width=320; } functionmakeNormal() { myVideo.width=420; }
注意:html5对于mp4文件支持,只能够为h264编码格式
音频
HTML5规定了一种通过audio元素来包含音频的标准方法。
audio元素能够播放声音文件或者音频流。
具体使用demo如下:
Your browser does not support the audio element.
注意:某些Android手机对于声音文件码率要求较高,所以建议声音文件尽量采用190kbps以上码率
1.3轻量级的js库Zepto.js+原生js代码提高web页面性能
Zepto.js的特点:
1.他够小,只有21k左右,功能俱全。
2.增加了移动设备的触摸等事件,不需要再次引入其他手机框架如jquery
mobile。
3.虽然不兼容ie但是提供了一个兼容方法:
document.write(‘
src=’+ (‘proto’in {} ?‘zepto’:‘jquery’) +‘.js></script>’) 。
1.4移动网页性能优化
概述 - PC优化手段在Mobile侧同样适用
2.在Mobile侧我们提出三秒种渲染完成首屏指标
3.基于第二点,首屏加载3秒完成或使用Loading
4.基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过****1014KB - Mobile侧因手机配置原因,除加载外渲染速度也是优化重点
6.基于第五点,要合理处理代码减少渲染损耗
7.基于第二、第五点,所有影响首屏加载和渲染的代码应在处理逻辑中后置
8.加载完成后用户交互使用时也需注意性能
优化指南
[加载优化]
加载过程是最为耗时的过程,可能会占到总耗时的80%时间,因此是优化的重点
·****减少****HTTP****请求
因为手机浏览器同时响应请求为4个请求(Android支持4个,iOS 5后可支持6个),所以要尽量减少页面的请求数,首次加载同时请求数不能超过****4****个
a)合并CSS、JavaScript
b)合并小图片,使用雪碧图
·****缓存
使用缓存可以减少向服务器的请求数,节省加载时间,所以所有静态资源都要在服务器端设置缓存,并且尽量使用长****Cache****(长****Cache****资源的更新可使用时间戳)
a)缓存一切可缓存的资源
b)使用长Cache(使用时间戳更新Cache)
c)使用外联式引用CSS、JavaScript
·****压缩****HTML****、****CSS****、****JavaScript
减少资源大小可以加快网页显示速度,所以要对****HTML****、****CSS****、****JavaScript****等进行代码压缩,并在服务器端设置****GZip
a)压缩(例如,多余的空格、换行符和缩进)
b)启用GZip
·****无阻塞
写在HTML头部的JavaScript(无异步),和写在HTML标签中的Style会阻塞页面的渲染,因此CSS****放在页面头部并使用****Link****方式引入,避免在****HTML****标签中写****Style****,****JavaScript****放在页面尾
部或使用异步方式加载
·****使用首屏加载
首屏的快速显示,可以大大提升用户对页面速度的感知,因此应尽量针对首屏的快速显示做优化
·****按需加载
将不影响首屏的资源和当前屏幕资源不用的资源放到用户需要时才加载,可以大大提升重要资源的显示速度和降低总体流量
PS:按需加载会导致大量重绘,影响渲染性能
a) LazyLoad
b)滚屏加载
c)通过Media Query加载
·****预加载
大型重资源页面(如游戏)可使用增加****Loading****的方法,资源加载完成后再显示页面。但****Loading****时间过长,会造成用户流失
对用户行为分析,可以在当前页加载下一页资源,提升速度
a)可感知Loading(如进入空间游戏的Loading)
b)不可感知的Loading(如提前加载下一页)
·****压缩图片
图片是最占流量的资源,因此尽量避免使用他,使用时选择最合适的格式(实现需求的前提下,以大小判断),合适的大小,然后使用智图压缩,同时在代码中用****Srcset****来按需显示
PS****:过度压缩图片大小影响图片显示效果
a)****使用智图(****http://zhitu.tencent.com/****)******
b)使用其它方式代替图片(1.使用CSS3 2.使用SVG 3.使用IconFont)
c)使用Srcset
d)选择合适的图片(1. webP优于JPG 2. PNG8优于GIF)
e)选择合适的大小(1.首次加载不大于1014KB 2.不宽于640(基于手机屏幕一般宽度))
·****减少****Cookie
Cookie会影响加载速度,所以静态资源域名不使用Cookie
·****避免重定向
重定向会影响加载速度,所以在服务器正确设置避免重定向
·****异步加载第三方资源
第三方资源不可控会影响页面的加载和显示,因此要异步加载第三方资源
[脚本执行优化]
脚本处理不当会阻塞页面加载、渲染,因此在使用时需当注意
· CSS****写在头部,****JavaScript****写在尾部或异步
·****避免图片和****iFrame****等的空****Src
空Src会重新加载当前页面,影响速度和效率
·****尽量避免重设图片大小
重设图片大小是指在页面、CSS、JavaScript等中多次重置图片大小,多次重设图片大小会引发图片的多次重绘,影响性能
·****图片尽量避免使用****DataURL
DataURL图片没有使用图片的压缩算法文件会变大,并且要解码后再渲染,加载慢耗时长
[CSS优化]
·****尽量避免写在****HTML****标签中写****Style****属性
·****避免****CSS****表达式
CSS表达式的执行需跳出CSS树的渲染,因此请避免CSS表达式
·****移除空的****CSS****规则
空的CSS规则增加了CSS文件的大小,且影响CSS树的执行,所以需移除空的CSS规则
·****正确使用****Display****的属性
Display属性会影响页面的渲染,因此请合理使用
a) display:inline后不应该再使用width、height、margin、padding以及float
b) display:inline-block后不应该再使用float
c) display:block后不应该再使用vertical-align
d) display:table-后不应该再使用margin或者float
·****不滥用****Float
Float在渲染时计算量比较大,尽量减少使用
·****不滥用****Web****字体
Web字体需要下载,解析,重绘当前页面,尽量减少使用
·****不声明过多的****Font-size
过多的Font-size引发CSS树的效率
·****值为****0****时不需要任何单位
为了浏览器的兼容性和性能,值为0时不要带单位
·****标准化各种浏览器前缀
a)无前缀应放在最后
b) CSS动画只用(-webkit-无前缀)两种即可
c)其它前缀为-webkit- -moz- -ms-无前缀四种,(-o-Opera浏览器改用blink内核,所以淘汰)
·****避免让选择符看起来像正则表达式
高级选择器执行耗时长且不易读懂,避免使用
[JavaScript执行优化]
·****减少重绘和回流
a)避免不必要的Dom操作
b)尽量改变Class而不是Style,使用classList代替className
c)避免使用document.write
d)减少drawImage
·****缓存****Dom****选择与计算
每次Dom选择都要计算,缓存他
·****缓存列表****.length
每次.length都要计算,用一个变量保存这个值
·****尽量使用事件代理,避免批量绑定事件
·****尽量使用****ID****选择器
ID选择器是最快的
· TOUCH****事件优化
使用touchstart、touchend代替click,因快影响速度快。但应注意Touch响应过快,易引发误操作
[渲染优化]
·HTML****使用****Viewport*
Viewport可以加速页面的渲染,请使用以下代码
**
content=”width=device-width, initial-scale=1″>
·****减少****Dom****节点
Dom节点太多影响页面的渲染,应尽量减少Dom节点
·****动画优化
a)尽量使用CSS3动画
b)合理使用requestAnimationFrame动画代替setTimeout
c)适当使用Canvas动画5个元素以内使用css动画,5个以上使用Canvas动画(iOS8可使用webGL)
·****高频事件优化
Touchmove、Scroll事件可导致多次渲染
a)使用requestAnimationFrame监听帧变化,使得在正确的时间进行渲染
b)增加响应变化的时间间隔,减少重绘次数
· GPU****加速
CSS中以下属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)来触发GPU渲染,请合理使用
PS:过渡使用会引发手机过耗电增加
1.5touch事件,touchstart, touchend, touchmove
iOS上的Safari也支持click和mouseover等传统的交互事件,只是不推荐在iOS的浏览器应用上使用click和mouseover,因为这两个事件是为了支持鼠标点击而设计出来的。Click事件在iOS上会有半秒左右的延迟,原因是iOS要highlight接收到click的element。而mouseover/out等事件则会被手指的点击触发。所以,在iOS上,应当抛弃传统的交互事件模型而接受一个新的事件模型。Touch事件和更高级的Gesture事件,能让你的网页交互起来像native应用一样。
三种在规范中列出并获得跨移动设备广泛实现的基本触摸事件:
1.touchstart:手指放在一个DOM元素上。
2.touchmove:手指拖曳一个DOM元素。
3.touchend:手指从一个DOM元素上移开。
每个触摸事件都包括了三个触摸列表: - touches:当前位于屏幕上的所有手指的一个列表。
- targetTouches:位于当前DOM元素上的手指的一个列表。
- changedTouches:涉及当前事件的手指的一个列表。
例如,在一个touchend事件中,这就会是移开的手指。
这些列表由包含了触摸信息的对象组成: - identifier:一个数值,唯一标识触摸会话(touch
session)中的当前手指。 - target:DOM元素,是动作所针对的目标。
3.客户/页面/屏幕坐标:动作在屏幕上发生的位置。
4.半径坐标和rotationAngle:画出大约相当于手指形状的椭圆形。
在开始描述touch事件之前,需要先描述一下多触式系统中特有的touch对象(android和iOS乃至nokia最新的meego系统都模拟了类似的对象,这里只针对iOS,因为我只有iPad可用于测试。。)。这个对象封装一次屏幕触摸,一般来自于手指。它在touch事件触发的时候产生,可以通过touch event handler的event对象取到(一般是通过event.changedTouches属性)。这个对象包括一些重要的属性:
client / clientY:触摸点相对于浏览器窗口viewport的位置
pageX / pageY:触摸点相对于页面的位置
screenX /screenY:触摸点相对于屏幕的位置
identifier:touch对象的unique ID
我们从一个单根手指触摸的实例开始进入多触式网页的世界。当一根手指放下的时候,屏幕上出现一个方块,手指移动方块也随着移动,手指提起方块消失。首先,让我们定义一下方块的css:
*{margin:0;padding:0}
html,body{height:100%}
.spirit{position:absolute;width:50px;height:50px;background-color:red;}
canvas{position:relative;width:100%;height:200px;background-color:#ccc}
然后,在body下定义一个接收事件的容器:
定义touchstart的事件处理函数,并绑定事件:
var canvas =document.getElementById("canvas"), spirit, startX, startY; functiontouchStart(event) { //阻止网页默认动作(即网页滚动) event.preventDefault(); if(spirit || !event.touches.length) return; var touch = event.touches[0]; startX = touch.pageX; startY = touch.pageY; spirit= document.createElement("div"); canvas.appendChild(spirit); spirit.className = "spirit"; spirit.style.left = startX + "px"; spirit.style.top = startY + "px"; }
canvas.addEventListener("touchstart",touchStart, false);
首先,我们将方块spirit作为一个全局对象,因为我们现在要测试单根手指所以屏幕上最好只有一个物体在移动(等会有多触实例)。在touchStart这个事件处理函数中,我们也首先判断了是否已经产生了spirit,也就是是否已经有一个手指放到屏幕上,如果是,直接返回。
和传统的event listener一样,多触式系统也会产生一个event对象,只不过这个对象要多出一些属性,比如这里的event.touches,这个数组对象获得屏幕上所有的touch。注意这里的event.preventDefault(),在传统的事件处理函数中,这个方法阻止事件的默认动作,触摸事件的默认动作是滚屏,我们不想屏幕动来动去的,所以先调用一下这个函数。我们取第一个touch,将其pageX/Y作为spirit创建时的初始位置。接下来,我们创建一个div,并且设置className,left,top三个属性。最后,我们把spirit对象appendChild到容器中。这样,当第一根手指放下的时候,一个红色的,50px见方的方块就放到屏幕上了。
然后,我们要开始处理手指在屏幕上移动的事件:
functiontouchMove(event) { event.preventDefault(); if(!spirit || !event.touches.length) return; var touch = event.touches[0], x = touch.pageX - startX, y = touch.pageY - startY; //这里是为了手指一定是横向滚动的,原理是计算X位置的偏移要比Y的偏移大 if(Math.abs(x) > Math.abs(y)) { spirit.style.left = touch.pageX + "px"; spirit.style.top = touch.pageY + "px"; } }
canvas.addEventListener("touchmove", touchMove, false);
在touch move listener中,我们使用webkit特有的css属性:webkitTransform来移动方块,这个属性具体怎么用请google之。建议构造面向iOS设备的网页的时候尽量使用webkit自己的特性,不但炫,更可以直接利用硬件来提高性能。
最后,我们处理touchend事件。手指提起的时候方块从屏幕上移除。
functiontouchEnd(event) { if(!spirit) return; canvas.removeChild(spirit); spirit = null; }
canvas.addEventListener("touchend",touchEnd, false);
2.页面框架pageframe.js的使用
2.1引用基础CSS
2.2引用Zepto.js库
2.3引用pageframe.js
2.4添加dom内容
11111111
222222
33333
4444444
55555555
2.5创建pageframe类并初始化
var myframe = new pageframe({
scene:'scene',
page:'page',
type :6,
loop :1,
auto :0,
callback : function(obj)
{
//alert(i);
//obj.css('background-color','red');
}
});
参数对着表
参数名称
取值
Scene
容器div class
Page
页面div class
Type
切换特效类型:0-普通横滑,1-页面横滑,2-翻转横滑,3-翻页横滑,4-飞页横滑
5-普通竖滑,6-页面竖滑,7-翻转竖滑,8-翻页竖滑,9-飞页竖滑
Loop
是否支持循环切换:0-不支持1-支持
Callback
页面切换完成后回调函数