在《使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 基础》中,Kayo 曾经简略介绍过 jQuery Mobile 的页面组件,当时只是举了一个简单的例子说明一下页面组件的情况,本文将会拓展说明页面组件的具体细节。
一.页面基础
在 jQuery Mobile 中,页面这个概念与传统的 Web 页面有一个很大的区别 —— jQuery Mobile 中的页面可以是单个的页面,也可以是一个页面中内嵌多个 "Page" ,“Page” 是 jQuery Mobile 中的页面,下面将会为大家详细介绍它。
Page 是 jQuery Mobile 的重要组成部分,由 data-role="page" 属性产生,每个 Page 由之前介绍过的 header , content , footer 组成,但这些元素并不是必须的,不过一个完整的页面最好同时都有这些元素。下面举一个例子,这也是《使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 基础》中的例子,为了方便大家阅读,这里重新例举一次。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<!
DOCTYPE
html>
<
html
>
<
head
>
<
title
>jQuery Mobile Demo</
title
>
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
/>
<
meta
name
=
"viewport"
content
=
"width=device-width, initial-scale=1"
>
<
link
rel
=
"stylesheet"
href
=
"http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css"
/>
<
script
type
=
"text/javascript"
src
=
"http://code.jquery.com/jquery-1.6.4.min.js"
></
script
>
<
script
type
=
"text/javascript"
src
=
"http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"
></
script
>
</
head
>
<
body
>
<
div
data-role
=
"page"
id
=
"home"
>
<
div
data-role
=
"header"
>
<
h1
>jQuery Mobile Demo</
h1
>
</
div
>
<
div
data-role
=
"content"
>
<
p
>主体内容</
p
>
</
div
>
<
div
data-role
=
"footer"
>
<
h2
>Footer</
h2
>
</
div
>
</
div
>
</
body
>
</
html
>
|
效果:
下面说明一下:
jQuery Mobile 网站必须使用 HTML5 的文档声明,使得这个网站能适用 HTML5 的特性,不支持这些特性的浏览器会安全地静默忽略 HTML5 的文档声明和一些属性。
HTML5 文档声明:
1
|
<!
DOCTYPE
html>
|
在页面 head 内,使用了 viewport 的 meta 标签控制了页面的缩放,例子中的 width=device- width, initial-scale=1 即控制页面宽度等于屏幕宽度,页面缩放比例为 1 ,这样浏览器就不会随意缩放页面了。
二.多页面结构
如上面所说,一个页面中可以内嵌多个 Page ,每个 Page 需要一个 ID 标记,页面间通过 “#ID” 的链接方式跳转,除第一个 Page 外,其他 Page 会使用隐藏起来,当链接被点击时, jQuery Mobile 会跳转到相应的 Page ,这个过程会以 Ajax 的方式完成,把新页面的内容加载到 DOM 中。
下面是一个多页面结构的代码参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<!
DOCTYPE
html>
<
html
>
<
head
>
<
title
>jQuery Mobile Demo</
title
>
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
/>
<
meta
name
=
"viewport"
content
=
"width=device-width, initial-scale=1"
>
<
link
rel
=
"stylesheet"
href
=
"http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css"
/>
<
script
src
=
"http://code.jquery.com/jquery-1.6.4.min.js"
></
script
>
<
script
src
=
"http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"
></
script
>
</
head
>
<
body
>
<
div
data-role
=
"page"
id
=
"home"
>
<
header
data-role
=
"header"
>
<
h1
>jQuery Mobile Demo</
h1
>
</
header
>
<
div
data-role
=
"content"
>
</
div
>
<
div
data-role
=
"footer"
>
<
h2
>Demo By <
a
href
=
"http://kayosite.com"
target
=
"_blank"
style
=
"text-decoration: none; "
>Kayo</
a
></
h2
>
</
div
>
</
div
>
<
div
data-role
=
"page"
id
=
"page-2"
>
<
div
data-role
=
"header"
>
<
h1
>Page 2</
h1
>
</
div
>
<!-- /header -->
<
div
data-role
=
"content"
>
</
div
>
<
div
data-role
=
"footer"
>
<
h2
>Demo By <
a
href
=
"http://kayosite.com"
target
=
"_blank"
style
=
"text-decoration: none; "
>Kayo</
a
></
h2
>
</
div
>
</
div
>
<
div
data-role
=
"page"
id
=
"page-3"
>
<
div
data-role
=
"header"
>
<
h1
>Page 3</
h1
>
</
div
>
<!-- /header -->
<
div
data-role
=
"content"
>
</
div
>
<
div
data-role
=
"footer"
>
<
h2
>Demo By <
a
href
=
"http://kayosite.com"
target
=
"_blank"
style
=
"text-decoration: none; "
>Kayo</
a
></
h2
>
</
div
>
</
div
>
</
body
>
</
html
>
|
三.Ajax 驱动的站点
jQuery Mobile 默认会以 Ajax 的方式构建网站和应用,因此,同一域名下的所有页面的跳转都会转为 Ajax 请求,并会配合 CSS3 动画作为页面跳转的过场。之所以采用这样的机制,一方面是因为移动设备所能用的网络速度相对 PC 来说会较低, Ajax 可以减少跳转到新页面所需的带宽,另一方面, Ajax 配合 CSS3 动画能做出原生 App 的用户体验。如:当用户点击一个链接时, jQuery Mobile 会分析该 url ,产生 Ajax 请求,并显示一个正在加载的提示框,避免了刷新整个页面。若该次 Ajax 请求成功,则会把新内容加载到 DOM 中,初始化所有组件,并显示页面过场动画。若请求失败,则会显示一个错误提示框,并在几秒后消失。
另外,带有 rel="external" 属性的链接不会通过 Ajax 方式加载,跳转时整个页面会被刷新。若需指定某个链接不需要 Ajax ,也可以为该链接添加 data-ajax="false" 属性,这样的链接也不会使用 Ajax 。关于 Ajax 的内容, Kayo 会在介绍配置 jQuery Mobile 时详细介绍。
四.页面转场
jQuery Mobile 为自带有一套基于 CSS3 的转场效果,你可以为任何能触发页面跳转的链接添加 data-transition 属性来调整转场动画效果。这些效果基于 CSS3 的 transitions ,某些移动平台对 transitions 的支持并不足够,如果你的页面在转场时出现闪烁的情况, Kayo 建议你在 CSS 中加入下面这一条 CSS 规则:
1
|
.ui-page { -webkit-backface-
visibility
:
hidden
; }
|
另外,若需要页面翻转等 3D 效果,浏览器必须支持 3D transforms ,若不支持(如安卓 2.x 系列),则会退化为淡出淡入的效果。
默认情况的转场效果是“fade”,即淡出淡入,若需要自定义转场效果,可以使用 data-transition 属性,如把转场效果改为“pop(弹出)”:
1
|
<
a
href
=
"#page2"
data-role
=
"button"
data-transition
=
"pop"
>dialog</
a
>
|
该属性的具体取值可以查看本文末的完整 Demo,里面列举了 data-transition 所有可取值。
小补充:控制转场宽度:当转场页面的宽度过大时,翻转等 3D 效果可能会过度消耗系统资源,因此开发者可以使用 $.mobile.maxTransitionWidth 控制转场最大宽度,超过该宽度则不使用转场动画。 $.mobile.maxTransitionWidth 是配置 jQuery Mobile 默认值的方法,因为比较复杂,将会另外写文章详解,这里列出该方法仅供有经验的开发者参考。
五.对话框
如下面的例子,为 Page 添加 data-rel="dialog" 属性,可以把页面表现为对话框的形式——增加圆角,外边距,阴影和遮罩层。
1
|
<
a
href
=
"#page-2"
data-role
=
"button"
data-rel
=
"dialog"
data-transition
=
"fade"
data-inline
=
"true"
>dialog</
a
>
|
对话框也是一个 Page ,因此也有转场效果,不过默认的效果是“slide”,即滑动出现。
需要注意的是,对话框通常作为辅助页面的用途(如登录框,提示框),因此 jQuery Mobile 不会在历史记录的哈希值里记录对话框。
六.jQuery Mobile 导航模型
看了上面的文字,也许你会对其中的内容感到迷惑!的确,jQuery Mobile 作为一套完善的移动前端解决方案,它的处理机制会比较复杂。这里 Kayo 介绍一下 jQuery Mobile 的导航模型,也就是 jQuery Mobile 的基本工作流程,了解完整的工作流程更有助于童鞋们理解上面的内容。
当一个 jQuery Mobile 文档被打开时,Page 容器被请求,插入到页面的 DOM 中,若页面中有多个 Page ,则会插入多个 Page ,但只有第一个 Page 在页面上会被直接显示,其他 Page 会隐藏起来,直到用户点击相应的链接才会以 Ajax 的方式跳转到另一个 Page 。
这就是 jQuery Mobile 导航的简单描述,jQuery Mobile 也就是在页面间跳转并处理 DOM 的,而这套机制都是基于 location.hash 属性的。当 jQuery Mobile 加载完第一个页面时,它会以页面相对于 url 的完整路径产生 hash 值,Ajax 不改变当前 url ,而改变 hash 值则可以保证当前 url 能表示当前的页面,如我们从 index.html 跳转到管理页面,则 url 也会更新为 index.html#admin(假设管理页面与主页在同一个 HTML 文档中并且 id 为 admin),这样这个 url 就能表示当前页面,若我们需要收藏这个页面,直接收藏即可。
于是最后就有了上面所说的 Ajax 驱动机制——当用户点击一个非外部链接时,hash 值发生变化,同时 jQuery Mobile 阻止链接的默认行为,并以 Ajax 的方式引入新内容,当新内容成功返回时更新 location.hash 的值,从而更新 url 。
现在整个导航模型以及 jQuery Mobile 的基本工作原理都已很清晰了,接下来再补充一点。在 jQuery Mobile 页面的 head 中,加入了一个 base 标签,该标签的值指向当前页面资源(图片,css,js)的正确获取路径,当页面变化时,base 的值也会作出相应的变化。
这里科普一下 base 标签,下面引用 w3school 对 base 标签的解释:
[bq]
<base> 标签为页面上的所有链接规定默认地址或默认目标。
通常情况下,浏览器会从当前文档的 URL 中提取相应的元素来填写相对 URL 中的空白。
使用 <base> 标签可以改变这一点。浏览器随后将不再使用当前文档的 URL,而使用指定的基本 URL 来解析所有的相对 URL。这其中包括 <a>、<img>、<link>、<form> 标签中的 URL。
[/bq]
七.预读取与缓存页面
开发者可以通过 data-prefetch 属性预读取一个页面,这样当你打开一个文档时,可以为另外一个文档在本文档中的链接添加 data-prefetch 来预先读取它,这个文档通常是用户很有可能点击的页面,这样对于提升用户体验具有不错的效果。
那为什么不直接把两页面放在同一个文档中呢?
因为如果把很多的 Page 放在一个文档中,这个文档的 DOM 会变得很大,这样对于一些性能较差的移动设备来说会造成压力,预读取的方式则可以减少这种压力。
比如我们需要缓存 page2.html (注意跟上面的 #page2 区分开来,这里的 page2.html 是独立的一个 HTML 文档),只需要在跳转到 page2.html 的链接上添加 data-prefetch 属性:
1
|
<
a
href
=
"Page2.html"
data-prefetch>Page2</
a
>
|
但这仍然会有问题, jQuery Mobile 会通过 Ajax 的方式加载页面,这样一旦点击的页面多了,DOM 将会变得很大,于是 jQuery Mobile 还做了一个机制来应对这个情况——当一个页面通过 Ajax 加载到 DOM 中后,jQuery Mobile 会标记这个页面,当导航到其他页面时,这个页面会从 DOM 中移除,从而保持 DOM 的干净。这个机制只适用于 Ajax 加载的其他文档的页面,同一页面的多个 Page 通过 Ajax 显示/隐藏并不适用于这个机制。
若需要缓存某个页面,以便用户从其他页面重新回到该页面时可以快速浏览可以使用 data-dom-cache="true" 属性:
如需要缓存上面例子中的 page2.html
1
|
<
a
href
=
"Page2.html"
data-prefetch
data-dom-cache
=
"true"
>Page2</
a
>
|
一旦缓存页面会使 DOM 变得很大,建议开发者在网站上线前进行足够的测试。
八.其他
多 Page 页面中虽然把第一个容器加载作为第一个页面,但实际上所有 Page 是同时存在于同一个文档中,因此需要注意保持页面中容器的 ID 唯一。
jQuery Mobile 通过 Ajax 请求页面,但它只会将新页面的 body 内容插入到 DOM 中,这意味着 head 部分引用的 js 对新内容无效,因此 Kayo 建议在每一个页面都引用相同的 js ,即把所有的 js 都写到同一文件中并在 head 中引用,并且这些 js 中用到的效果最好使用 live, delegate 等持续性方法匹配到元素中,这样 js 中的效果对通过 Ajax 引入的新元素也有效。当然,jQuery Mobile 中的 js 的所有方法都已经采用了相似的办法使到其对新元素也有效。当然,开发者也可以使用 pagecreate() 的方法为某一个页面指定一个 js ,关于这个方法会在另外的文章中介绍。
九.完整 Demo
完整实例 Demo(建议使用 PC 上的 Firefox、Chrome 等现代浏览器和 IE9+ 或 Android , iPhone/iPad 的系统浏览器浏览)
本文由 Kayo Lee 发表,本文链接:http://kayosite.com/web-app-by-jquery-mobile-and-html5-page-dialog.html