jQuery Mobile 高级教程(全)
原文:Pro jQuery Mobile
协议:CC BY-NC-SA 4.0
零、简介
我们目前正在见证企业和个人构建和分发移动应用的方式的转变。最初的策略是为每个主要平台构建单独的原生应用。然而,团队很快意识到维护多个平台是不可持续的,因为移动团队失去了灵活性。可以一次构建并在明天发布到所有设备的移动团队将拥有竞争优势,jQuery Mobile 可以帮助您实现这一目标。
jQuery Mobile 是一个框架,用于交付具有统一接口的跨平台移动 web 应用。jQuery Mobile 将响应式布局与渐进式增强相结合,从单一代码库提供尽可能好的用户体验。通过 jQuery Mobile,我们将看到如何为 iOS、Android、Windows Phone、Blackberry 等创建可操作的、响应迅速的、具有本机外观的应用。我们将发现 jQuery Mobile 与其他移动 web 开发平台的不同之处,并且我们将浏览 jQuery Mobile 特性的实际例子,包括设计元素和事件处理。
你将学到什么
- jQuery Mobile 的独特功能
- jQuery Mobile 的核心特性,包括页面结构、导航、表单元素、列表和网格
- 如何创造主题化的设计
- 整个 jQuery Mobile API,包括数据属性、方法和事件
- 将 web 服务、Google 地图和地理定位集成到您的 jQuery Mobile 应用中
- 当您需要分发到应用商店或访问设备功能时,如何使用 PhoneGap 扩展 jQuery Mobile
- 如何将 jQuery Mobile 应用于具体案例,包括 iOS 和 Android 应用
这本书是给谁的
希望掌握 jQuery Mobile 并从单一代码库构建跨平台移动 web 应用的移动开发人员。
下载代码
读者可以在本书主页的源代码部分的[
www.apress.com](http://www.apress.com)
获得本书的源代码。请随意访问 Apress 网站并在那里下载代码。
一、为什么选择 jQuery Mobile?
jQuery Mobile 是一个简单易用的新 UI 框架,用于构建跨平台的移动 Web 应用。在几分钟内,您就可以创建移动应用(apps ),这些应用已经过优化,可以在目前可用的几乎所有手机、平板电脑、台式机和电子阅读器设备上运行。没错,通过单一的 jQuery Mobile 代码库,我们可以为几乎所有的消费者创造统一的体验。对于任何需要一个简单框架来创建丰富的移动 Web 体验的 Web 设计人员或开发人员来说,jQuery Mobile 是一个理想的框架。这种体验也超越了网络。jQuery Mobile 应用也可以用混合技术编译,在您喜欢的本地应用商店中发布。在开始我们的旅程时,让我们回顾一下使 jQuery Mobile 与众不同的重要特性。
普遍接入
所有带有浏览器的设备都可以访问 jQuery Mobile 应用。这是 jQuery Mobile 的分发模式的有利优势(参见 Figure 1–1)。几乎每个移动设备都带有浏览器。如果你的应用可以被广泛使用,这将是一个主要的竞争优势。下面是 jQuery Mobile 1.0 支持的设备的完整列表,包括大多数手机、平板电脑、桌面浏览器,甚至电子阅读器。
图 1–1。jQuery 1.0 手机浏览器覆盖
支持的设备:
- 手机/平板电脑
- 安卓 1.6 以上
- 黑莓 5+
- iOS 3+
- Windows Phone 7
- WebOS 1.4 以上版本
- 塞班(诺基亚 S60)
- 火狐手机歌剧移动 11+
- Opera Mini 5+
- 桌面浏览器
- 铬合金 11+
- 火狐 3.6 以上版本
- Internet Explorer 7+
- 旅行队
- 电子书阅读器
- 点燃
- 角落
注:关于所有支持平台的最新列表,请参考 jQuery Mobile 的支持平台页面(参见jquerymobile.com/gbs/
)。
相比之下,本地应用开发有一个非常严格的分布模型(参见 Figure 1–2)。本机应用仅在其本机操作系统上可用。例如,iPhone 应用只能通过 iOS 设备访问。如果你的目标是接触尽可能多的消费者,这种分销模式是有限的。幸运的是,jQuery Mobile 应用没有受到这种分布障碍的限制。
图 1–2。 原生 OS 覆盖范围
除了通用访问之外,jQuery Mobile 应用还可以利用我们在 Web 上已经习惯的即时部署功能。对于 jQuery Mobile 应用,在本地应用分发模型中要求的认证审查方面不存在任何障碍。移动 Web 应用可以即时更新并部署到您的生产用户。例如,我最近正在开发一个需要更新的本地企业应用,而重新认证流程花了一周时间才批准了这一更改。平心而论,本地应用商店可以选择提交紧急更新,但关键是你将依赖第三方来推送更新到他们的商店。移动网络的即时部署模式在这方面非常有利。
跨所有移动平台的统一 UI
jQuery Mobile 按照 HTML5 和 CSS3 标准设计,提供了统一的用户界面。移动用户希望他们的用户体验跨平台保持一致(参见图 1–3、图 1–4、图 1–5)。相反,比较 iPhone 和 Android 上的原生 Twitter 应用。体验不统一。jQuery Mobile 应用弥补了这种不一致性,提供了一种熟悉的、可预期的用户体验,而与平台无关。此外,无论最终用户平台如何,统一的用户界面都将提供一致的文档、屏幕截图和培训。例如,如果您的销售人员需要关于正在部署的新移动应用的培训,用户文档将包含适用于所有平台的一致屏幕截图。如果团队中一半人使用 iPhones,另一半人使用 Android 设备,那么所有用户的培训体验和文档都是一样的。
图 1-3。 iPhone
图 1–4。 Windows Phone
图 1-5。 Android
jQuery Mobile 还有助于消除对特定于设备的 UI 定制的需求。无需定制,单个 jQuery Mobile 代码库将在所有支持的平台上一致地呈现。与支持每个操作系统的本地代码库的组织相比,这是一个非常经济高效的解决方案。从支持和维护成本的角度来看,支持单一代码库更具成本效益(参见图 1–6)。
图 1–6。 通过移动技术叠加成本乘数
简化的标记驱动开发
jQuery Mobile 页面采用 HTML5 标记样式(参见清单 1–1)。).除了 HTML5 中引入的新的自定义数据属性之外,对于 Web 设计人员和开发人员来说,一切都应该非常熟悉。如果您已经熟悉 HTML5,那么迁移到 jQuery Mobile 应该是一个相对无缝的过渡。关于 JavaScript 和 CSS,默认情况下,jQuery Mobile 完成了所有繁重的工作。但是,在某些情况下,您可能需要依靠 JavaScript 来创建更动态或增强的页面体验。除了设计页面所需的简单标记外,它还允许用户界面的快速原型化。很快,我们可以创建一个功能页面、过渡和小部件的静态工作流,以帮助我们的客户用最少的努力看到真实的原型。
清单 1–1。 在此插入清单标题。
`
Page Header
Hello jQuery Mobile!
Page Footer
渐进增强
jQuery Mobile 将为设备呈现最优雅的用户体验。例如,看看图 1–7 中的 jQuery Mobile switch 控件。这是 A 级浏览器上的开关控件。 1
A 级浏览器支持媒体查询,并将呈现 jQuery Mobile CSS3 风格的最佳体验。
图 1–7。 A 级体验
图 1–8。 C 级经验
jQuery Mobile 呈现应用了完整 CSS3 样式的控件。或者,Figure 1–8 是在更老的 C 级浏览器上呈现的相同开关控件。2C 级浏览器不渲染完整的 CSS3 样式。
重要提示:尽管 C 级体验不是最具视觉吸引力的,但它证明了优雅降级的有用性。随着用户升级到更新的设备,C 级浏览器市场最终将会缩小。在这种交叉发生之前,C 级浏览器在运行 jQuery Mobile 应用时仍将获得功能性用户体验。
本机应用并不总是优雅地降级。在大多数情况下,如果您的设备不支持本机应用功能,您甚至不允许下载该应用。例如,iOS 5 中的一个新功能是 iCloud persistence。这项新功能简化了多个设备之间的数据同步。为了兼容性,如果我们创建一个包含这一新功能的新 iOS 应用,我们将需要为我们的应用设置“最低允许的 SDK”为 5.0。现在,我们的应用将只对运行 iOS 5.0 或更高版本的用户可见。jQuery Mobile 应用在这方面更加灵活。
C 级浏览器不支持媒体查询,也不会从 jQuery Mobile 获得样式增强。
响应式设计
jQuery Mobile UI 将在不同的显示尺寸之间做出相应的呈现。例如,相同的用户界面将适当地显示在手机上(参见图 1–9)或更大的设备上,如平板电脑、台式机或电视(参见图 1–10)。
图 1–9。 手机显示
图 1–10。 平板电脑/台式机/电视显示器
一次构建,随处运行的神话
有没有可能构建一个对所有消费者(手机、台式机、平板电脑)通用的单一应用?是的,这是可能的。网络提供全球分销。jQuery Mobile 提供跨浏览器支持。有了 CSS 媒体查询,我们可以开始定制我们的用户界面,以最适合的形式因素。例如,在小型设备上,我们可以提供带有简短内容的小图像,而在大型设备上,我们可以提供带有详细内容的大图像。如今,大多数拥有移动设备的组织通常同时支持桌面网站和移动网站。你必须支持一个应用的多个发行版,这是浪费时间。组织拥抱移动存在的速度,加上他们避免浪费的需要,将推动“构建一次,随处运行”的神话成为现实。
响应式
在某些情况下,jQuery Mobile 会为您创建响应式设计。下图显示了 jQuery Mobile 的响应式设计在纵向和横向模式下应用于表单域定位的效果。例如,在纵向视图中(参见图 1–11),标签位于表单字段上方。或者,在横向重新定位设备时(参见图 1–12),表单域和标签并排出现。这种响应式设计基于可用于筛选房地产的设备提供了最有用的体验。jQuery Mobile 为您提供了许多这些好的 UX 原则,而无需您付出任何努力!
图 1–11。 响应式设计(人像)
图 1–12。 响应式设计(景观)
主题风格
jQuery Mobile 支持主题化设计,允许设计者快速地重新设计他们的 UI。默认情况下,jQuery Mobile 提供了五种主题设计,可以灵活地交换所有组件的主题,包括页面、页眉、内容和页脚组件。创建自定义主题最有用的工具是滚轮 3 。
重新设计一个用户界面需要最少的努力。例如,我可以快速获得一个默认主题的 jQuery Mobile 应用(参见 Figure 1–13),然后在几秒钟内用另一个内置主题重新设计它。在我修改主题的情况下(见图 1–14,我从列表中选择了一个替换主题。唯一需要的标记是添加一个数据主题属性。我们将在《??》第七章中更详细地讨论主题。
`
- `
- jQuery Mobile 应用可以在所有带浏览器的设备上通用,并且已经过优化,可以在目前几乎所有的手机、平板电脑、台式机和电子阅读器设备上运行。
- jQuery Mobile 应用可以利用我们在 Web 上已经习惯的即时部署功能。
- 无需定制,单个 jQuery Mobile 代码库将在所有支持的平台上一致地呈现。与为每个操作系统或客户端构建应用的替代方案相比,这是一个非常经济高效的解决方案。
- jQuery Mobile 是一个简化的标记驱动框架,Web 设计人员和开发人员应该对此非常熟悉。您可能会感到非常惊讶和兴奋,因为您可以用 100%的标记构建 jQuery Mobile 应用!
- jQuery Mobile 利用渐进式增强技术为所有 A 级设备提供非常丰富的体验,并为旧的 C 级浏览器提供可用的体验。
- jQuery Mobile UI 将在各种大小的设备上响应性地呈现,包括手机、平板电脑、台式机或电视。
- jQuery Mobile 支持主题化设计,允许设计者在全球范围内快速地重新设计他们的 UI。
- 所有 jQuery Mobile 应用都符合 508 标准。
- 这是 jQuery Mobile 的推荐视口配置。
device-width
值表示我们希望内容缩放设备的整个宽度。initial-scale
设置设定用于查看网页的初始比例或缩放系数。值 1 显示未缩放的文档。作为 jQuery Mobile 开发人员,您可以根据自己的应用需求定制视口设置。例如,如果你想禁用缩放,你可以添加user-scalable=no
。但是,禁用缩放是一种您希望尽量避免的做法,因为它会破坏可访问性。 - jQuery Mobile 的 CSS 将为所有 A 级和 B 级浏览器应用风格增强。您可以根据需要自定义或添加自己的 CSS。
- jQuery 库是 jQuery Mobile 的核心依赖项,如果您的应用需要更动态的行为,强烈建议您在移动页面中利用 jQuery 的核心 API。
- 如果您需要覆盖 jQuery Mobile 的默认配置,可以在这里应用您的定制。有关定制 jQuery Mobile 默认配置的详细信息,请参考第八章,配置 jQuery Mobile。
- jQuery Mobile JavaScript 库必须在 jQuery 和任何自定义脚本之后声明。jQuery Mobile 库是增强整个移动体验的核心。
data-role=“page”
为 jQuery Mobile 页面定义页面容器。只有在构建多页面设计时才需要这个元素(参见清单 2–3)。data-role="header"
是如图图 2–1 所示的标题或标题栏。该属性是可选的。data-role=“content”
是内容体的包装容器。该属性是可选的。data-role=“footer”
包含如图图 2–1 所示的页脚条。该属性是可选的。- 首先,jQuery Mobile 将加载语义 HTML 标记(参见清单 2–1)。
- 接下来,jQuery Mobile 将迭代每个页面组件,由它们的数据角色属性定义。随着 jQuery Mobile 迭代每个页面组件,它将增强标记,并为每个组件应用移动优化的 CSS3 增强。jQuery Mobile 最终将标记增强为一个页面,可以在所有移动平台上通用地呈现。
- 最后,在页面增强完成后,jQuery Mobile 将显示优化后的页面。请参见清单 2–2 查看由移动浏览器呈现的增强源代码。
- base 标签的
@href
指定了页面上所有链接的默认地址或默认目标。例如,jQuery Mobile 将在加载特定于页面的资产(图片、CSS、js 等)时利用@href
。). - body 标签包含了
header, content,
和footer
组件的增强样式。默认情况下,所有组件都使用了默认主题及其特定于移动设备的 CSS 增强功能。另外,由于增加了 WAI-ARIA 角色和级别,所有组件现在都支持可访问性。您可以免费获得所有这些增强功能! - 多页文档中的每一页都必须包含唯一的
id
。一个页面可以有一个page
或dialog
的data-role
。当最初显示多页文档时,仅增强并显示第一页。例如,当请求multi-page.html
文档时,将显示带有id=“home”
的页面,因为它是多页文档中列出的第一页。如果您想要请求带有id=“contact”
的页面,您可以请求带有您想要显示的内部页面散列的多页文档(multi-page.html#contact
)。当加载多页文档时,只会增强和显示初始页面。后续页面在被请求并缓存在 DOM 中时会得到增强。这种行为非常适合快速响应。要设置每个内部页面的标题,添加data-title
属性。 - 当链接到内部页面时,您必须通过页面
id
引用它。例如,链接到联系人页面的 href 必须设置为href=“#contact”
。 - 如果您想将脚本的范围限定在特定的页面上,它们必须放在页面容器中。这条规则也适用于通过 Ajax 加载的页面,我们将在下一节进一步讨论。例如,
multi-page.html#home
将无法访问任何在multi-page.html#contact
上内部声明的 JavaScript。只能访问活动页面的脚本。然而,所有的脚本,包括 jQuery、jQuery Mobile 和您自己在父文档的 head 标签中声明的定制脚本,对于所有内部和 Ajax 加载的页面都是可用的。 - 如果存在一个
data-ti2–tle
值,它将被用作内部页面的标题。例如,“multi-page.html#home”
的标题将被设置为“Home”
。 - 如果不存在
data-title
值,页眉将被用作内页的标题。例如,如果"multi-page.html#home"
没有data-title
属性,那么标题将被设置为"Welcome Home"
,即它的header
标签的值。 - 最后,如果内部页面上既没有
data-title
也没有标题,那么 head 标签中的 title 元素将被用作内部页面的标题。例如,如果"multi-page.html#home
没有data-title
属性和标题,那么标题将被设置为"Multi Page Example"
,即父文档标题标签的值。 -
jQuery Mobile will parse the
href
and load the page via an Ajax request (Hijax). For a visual, refer to Figure 2–3. If the page is loaded successfully, it will be added to the DOM of the current page.图 2–3。 jQuery Mobile Hijax 请求
页面成功添加到 DOM 后,jQuery Mobile 将根据需要增强页面,更新
base
元素的@href
,并设置data-url
属性(如果没有显式设置的话)。 -
然后,框架将转换到新页面,并应用默认的“
slide
”转换。框架能够实现无缝的 CSS 转换,因为“from”和“to”页面同时存在于 DOM 中。过渡完成后,当前可见或活动的页面将被赋予“ui-page-active”CSS 类。 -
The resulting URL is also bookmarkable. For example, if you want to deep link to the contact page you may access it from its full path:
[
host:port/ch2/contact.html](http://<host:port>/ch2/contact.html).
注意:作为一个额外的好处,基于 Ajax 的导航也将在支持 HTML5 的 pushState 的浏览器中产生干净的 URL。桌面 Safari、Chrome、Firefox 和 Opera 的最新版本都支持该功能。Android (2.2+)和 iOS5 也支持 pushState。在不支持此功能的浏览器中,将使用基于散列的 URL(
[
host:port/hijax.html#contact.html](http://<host:port>/hijax.html#contact.html)
)来保留共享和标记 URL 的能力。 -
如果任何页面在 jQuery Mobile 中加载失败,将会显示一个“加载页面错误”的小错误消息覆盖图并淡出(参见图 2–4)。
- changePage 函数处理从一个页面转换到另一个页面的所有细节。您可以切换到除同一页面之外的任何页面。可用过渡类型的完整列表如表 2–1 所示。
- $.mobile.changePage(“选项”)
**toPage**
(字符串或 jQuery 集合)。要转换到的页面。toPage
(字符串)。文件 URL ("contact.html"
)或内部元素的 ID(#contact
)。toPage
(jQuery 集合)。包含页面元素作为第一个参数的 jQuery 集合。
**options**
(对象)。配置 changePage 请求的一组键/值对。所有设置都是可选的。transition
(字符串,默认:$ . mobile . default transition)。申请变更页面的过渡。默认过渡是"slide"
。reverse
(布尔,默认:false
)。以指示过渡应该向前还是向后。默认转换是向前。changeHash
(布尔,默认:true
)。当页面更改完成时,将哈希更新为页面的 URL。role
(字符串,默认:"page"
)。显示页面时要使用的数据角色值。对于对话框,使用"dialog"
。pageContainer
(jQuery 集合,默认:$.mobile.pageContainer
)。指定页面加载后应包含的元素。type
(字符串,默认:"get"
)。指定发出页面请求时使用的方法(“get
或“post
”)。data
(字符串或对象,默认:未定义)。发送到 Ajax 页面请求的数据。reloadPage
(布尔,默认:false
)。强制重新加载页面,即使它已经在页面容器的 DOM 中。showLoadMsg
(布尔,默认:true
)。请求页面时显示加载消息。fromHashChange
(布尔,默认:false
)。指示 changePage 是否来自 hashchange 事件。
- 用户点击按钮导航至下一页(参见图 2–5)。
- 框架将使用 Hijax 请求加载下一个页面,并将其添加到当前页面的 DOM 中。当两页基本并排时,平滑过渡就要开始了(见图 2–6)。
- 框架转换到下一页(见图 2–7)。此示例使用默认的“幻灯片”过渡。
- 显示下一页,过渡完成(参见图 2–8)。
- 优先选择显示影响应用使用的重要信息的警告(参见图 2–10)。警报是而不是用户发起的。
- 警告按钮要么是浅色的,要么是深色的。对于单按钮警报,按钮总是浅色的。对于双按钮对话框,左按钮总是暗的,右按钮总是亮的(参见图 2–9)。
- 在一个双按钮对话框中,建议一个人们可能会选择的有利动作,取消该动作的按钮应该在左边,并且是深色的(参见 Figure 2–9)。
- 在两个按钮的对话框中,建议一个有潜在风险的操作(删除),取消操作的按钮应该在右边并且是浅色的。通常执行危险动作的按钮是红色的。
- 优选行动表来收集对用户发起的任务的确认(参见图 2–11)。行动表也可用于为用户提供当前任务的选择范围(参见图 2–12)。
- 动作表总是包含至少两个按钮,允许用户选择如何完成他们的任务。
- 包括允许用户放弃任务的取消按钮。“取消”按钮位于操作表的底部,以鼓励用户在做出选择之前通读所有选项。“取消”按钮的颜色应该与背景的颜色相对应。
- 您可以禁用缩放。尽管如此,禁用缩放是一种您希望尽量避免的做法,因为它会破坏可访问性。
<meta name="viewport" content="width=device-width, **minimum-scale=1.0, maximum-scale=1.0"**
- 当用户缩放时,您可以动态调整 meta 标签。 7
- 标题是用
data-role="header"
属性定义的。 - 标题是一个可选组件。
- 除非您明确启用后退按钮,否则它不会显示在标题中。下一节将详细讨论后退按钮。
- 您可以使用
data-theme
属性调整页眉的主题。如果没有为标题设置主题,它将从页面组件继承主题。默认主题是黑色(data-theme="a"
)。 - 默认情况下,所有标题级别(H1-H6)的样式相同,以保持视觉一致性。
- 您可以通过添加
data-position="fixed"
属性来固定标题。 - 默认:一个默认的标题将显示在屏幕的顶部,当你滚动时会滑出屏幕。``
Default Header
- 固定:一个固定的标题将始终保持定位,并在屏幕的顶部边缘可见。然而,在滚动事件期间,标题将会消失,直到滚动完成。我们可以创建一个添加了
data-position="fixed"
属性的固定头。``
Fixed Header
- 响应式:当我们创建一个全屏页面时,内容会边对边地出现,页眉和页脚会根据触摸响应相应地出现和消失。全屏模式对于照片或视频显示非常有用。要创建全屏页面,将
data-fullscreen="true"
添加到页面容器中,并在页眉和页脚元素中包含data-position="fixed"
属性(参见清单 3–1)。例如,在图 3–1 中,我们有一个显示照片的全屏页面。如果用户点击屏幕,页眉和页脚将相应地出现和消失(参见图 3–2)。在本例中,我们有一个照片查看器,其页眉显示图像面板的计数器,页脚显示一个工具栏来帮助导航、发送电子邮件或删除图像。 -
只有文本的按钮。
-
只有图标的按钮(参见图 3–4)。一个纯图标按钮需要添加两个属性:
data-icon
和data-iconpos="notext"
。关于data-icon
值的完整列表,请参考表 4-1 。 -
一个带有文本和图标的按钮(参见图 3–3)。这个按钮还需要
data-icon
属性。这里显示了每个示例:`
Done<a href="#" data-icon="plus" data-iconpos="notext">
<a href="#" data-icon="check">Done`
- 您可以通过在页面容器上添加
data-auto-back-btn="true"
来将后退按钮添加到特定页面。 - 绑定
mobileinit
选项时,通过将addBackBtn
选项设置为true
可以全局启用后退按钮。设置此选项后,如果历史堆栈中存在页面,后退按钮将自动出现。在幕后,一个后退按钮简单地执行window.history.back()
。如下所示,您也可以覆盖默认的后退按钮文本和主题。例如,用上一页的标题标记后退按钮是很常见的。data-back-btn-text
属性可以用于这个约定。有关设置全局配置选项的更多详细信息,请参考第八章,配置 jQuery Mobile。 - 页脚用
data-role="footer"
属性定义。 - 页脚将其按钮从左到右按顺序内联放置。这允许灵活地创建工具栏和选项卡栏。
- 页脚是一个可选组件。
- 您可以使用
data-theme
属性调整页脚的主题。如果没有为页脚设置主题,它将从页面组件继承主题。默认主题是黑色(data-theme="a"
)。 - 您可以通过添加
data-position="fixed"
属性来固定页脚。 - 默认情况下,所有页脚(H1-H6)的样式相同,以保持视觉一致性。
- Default:默认页脚位于内容部分之后。例如,如果您的内容超出了视窗的高度,页脚将不会显示,直到您滚动到内容的末尾。``
- 固定:一个固定的页脚,将始终保持定位,并在屏幕的底部边缘可见。然而,在滚动事件期间,页脚将会消失,直到滚动完成。我们可以创建一个添加了
data-position="fixed"
属性的固定页脚。`<div data-role="footer" data-position="fixed">
Fixed Footer
- 响应式:当我们创建一个全屏页面时,内容会边对边显示,页眉和页脚会根据触摸响应相应地出现和消失。全屏模式对于照片或视频显示非常有用。要创建全屏页面,请将
data-fullscreen="true"
添加到页面容器中,并在页眉和页脚元素中包含data-position="fixed"
属性。有关示例,请参考图 3–1。
3 见[
jqueryui.com/themeroller/](http://jqueryui.com/themeroller/)
。ThemeRoller 是一个基于 web 的工具,可以自动生成新的基于 CSS 的主题。
图 1–13。 默认主题
图 1–14。 交替主题
可及
默认情况下,jQuery Mobile 应用符合 508 标准,这一特性对任何人都很有价值。 4
特别是,政府或国家机构要求他们的应用 100%可访问。此外,移动屏幕阅读器的使用正在上升。根据 WebAIM 5 的调查,66.7%的屏幕阅读器用户在他们的移动设备上使用屏幕阅读器。
4 508 合规性是一项联邦法律,要求残疾用户能够访问应用。移动网络上最常用的辅助技术是屏幕阅读器。
5 见[
webaim.org/projects/screenreadersurvey3/#mobileusage](http://webaim.org/projects/screenreadersurvey3/#mobileusage)
。
提示:有兴趣测试你的移动网站是否符合 508 标准吗?使用 WAVE 评估您的移动网站。 6
除了用 WAVE 测试你的移动应用的可访问性,用实际的辅助技术测试你的移动网络应用也是有价值的。例如,如果你有一个 iOS 设备,激活苹果的辅助工具,VoiceOver 7 并亲自体验该行为。
注意:如果您有兴趣查看现有的 jQuery Mobile 应用,可以使用在线 jQuery Mobile 图库获取想法和灵感(参见[
www.jqmgallery.com/](http://www.jqmgallery.com/)
)。
总结
在本章中,我们回顾了使 jQuery Mobile 独一无二的重要特性:
6 见[
wave.webaim.org/](http://wave.webaim.org/)
。
7 见[
www.apple.com/accessibility/iphone/vision.html](http://www.apple.com/accessibility/iphone/vision.html)
。
二、jQuery Mobile 入门
在第一章中,我们回顾了 jQuery Mobile 的独特之处。现在,我们将回顾 jQuery Mobile 的基础知识,以便我们可以快速启动并运行它。我们将从 jQuery Mobile 页面模板的概述开始。实际上有两种页面模板可供选择,我们将讨论每种模板的优势。接下来,我们将深入了解 jQuery Mobile 如何将我们的语义标记增强为优化的移动体验。此外,我们将探索 jQuery Mobile 导航模型是如何工作的。尽管 jQuery Mobile 管理着整个导航体验,但是理解导航模型是如何工作的也很重要。最后,我们将向您展示如何让页面过渡真正“流行”急着出发吗?让我们从一个 jQuery Mobile 页面的例子开始。
jQuery Mobile 页面模板
一个 jQuery Mobile 页面模板显示在清单 2–1 中。在我们继续下一步之前,让我们开始吧。复制 HTML 模板(ch2/template.html),将其粘贴到桌面上,并从您喜欢的浏览器中启动它。您现在正在运行一个 jQuery Mobile 应用,无论您使用什么浏览器,它看起来都应该与图 2–1 一样!该模板是语义 HTML5,包含 jQuery Mobile 特定的属性和资产文件(CSS、js)。在清单 2–1 中突出显示并解释了每个特定的 jQuery Mobile 资产和属性。
清单 2–1。 jQuery 手机页面模板(ch2/template.html)
`
*<div data-role="page"> * 6
<div data-role="header"> 7
Page Header
<div data-role="content"> 8
Hello jQuery Mobile!
<div data-role="footer"> 9
Page Footer
`
重要提示:CSS 和 JavaScript 文件的顺序必须按照清单 2–1 中列出的顺序出现。在 jQuery Mobile 引用依赖项之前,需要对依赖项进行排序以正确初始化。此外,建议从内容交付网络(CDN)下载这些文件。特别是,您可以从 jQuery Mobile CDN 下载它们。1cdn 中的文件经过高度优化,将为您的用户提供更灵敏的体验。它们被压缩、缓存、缩小,并且可以并行加载!
图 2–1。 你好 jQuery 手机
1 见【http://jquerymobile.com/download/】的。
提示:要将页脚定位在屏幕的最底部,向页脚元素添加data-position=“fixed”
。默认页脚位于内容之后,而不是设备的底部。例如,如果你的内容只占设备高度的一半,页脚就会出现在屏幕的中间。
<div data-role=“footer”
数据-位置= "固定" >
jQuery Mobile 页面增强功能
jQuery Mobile 如何增强标记以优化移动体验?有关目测,请参考图 2–2。
图 2–2。 jQuery Mobile 页面增强示意图
清单 2–2。jQuery Mobile 增强版 DOM
`
<html class="ui-mobile> <head> **<base href="http://www.server.com/app-name/path/">** 1 <meta charset="utf-8"> <title>Page Header</title> <meta content="width=device-width, initial-scale=1" name="viewport"> <link rel="stylesheet" type="text/css" href="jquery.mobile-min.css" /> <script type="text/javascript" src="jquery-min.js"></script> <script type="text/javascript" src="jquery.mobile-min.js"></script> </head> 2
Hello jQuery Mobile!
loading
到目前为止,您应该对设计一个基本的 jQuery Mobile 页面感到满意了。已经向您介绍了核心页面组件(page, header, content, footer
),并且已经看到了增强的 jQuery Mobile 页面的 DOM 结果。接下来我们将探索 jQuery Mobile 的多页面模板。
多页模板
jQuery Mobile 支持在单个 HTML 文档中嵌入多个页面的能力,如清单 2–3 所示。这种策略可用于预先预取多个页面,并在加载子页时实现更快的响应时间。正如您在下面的示例中看到的,多页文档与我们之前看到的单页模板完全相同,只是在第一页之后附加了第二页。下面突出显示并讨论了多页的具体细节。
清单 2–3。ch2/multi-page.html
多页模板
`
</head> <body>
Welcome Home
<a href="#contact" data-role="button">Contact Us 2
Contact Us
Contact information...
设置内部页面的页面标题
需要注意的是,内部页面的标题将按照以下优先顺序设置:
重要提示:当链接到一个包含多个页面的页面时,必须将rel="external"
添加到其链接中。
`
Home
Home`
这将执行整页刷新。这是必需的,因为 jQuery Mobile 不能将多页面文档加载到活动页面的 DOM 中。这将导致与 jQuery Mobile 如何利用 URL 哈希(#)的名称空间冲突。jQuery Mobile 利用哈希值来识别多页面文档中的内部页面。
此外,因为 jQuery Mobile 利用散列来识别 DOM 中的唯一页面,所以不可能利用锚标记书签特性(index.html#my-bookmark
)。jQuery Mobile 将my-bookmark
视为页面标识符,而不是书签。Ajax 驱动的导航将在下一节详细讨论。
单页文档与多页文档
您需要确定页面访问趋势,以确定从带宽和响应时间的角度来看哪种策略最有意义。多页文档在初始加载时会消耗更多的带宽,但它们只需要一个服务器请求,因此它们的子页面加载的响应时间非常快。单页文档每次请求消耗的带宽较少,但是每页需要一个服务器请求,这导致响应时间非常慢。
如果你有几个经常按顺序访问的页面,它们是在同一文档中预先加载的理想选择。最初的带宽命中率稍高,但我们在访问下一页时实现了即时响应。但是,如果用户访问两个页面的概率很低,那么您应该选择将文件分开,并在初始加载时达到较低的带宽。
有工具可以帮助您收集页面访问趋势和其他指标,以帮助优化您的页面访问策略。比如 Google Analytics2或者 Omniture 3 都是移动 Web 应用常见的分析解决方案。
2 见【http://www.google.com/analytics/】的。
3 见【http://www.omniture.com/】的。
提示:在大多数情况下,建议利用单页面模型,在后台将流行页面动态追加到 DOM 中。我们可以通过向任何想要动态加载的链接添加data-prefetch
属性来实现这种行为:
<a href="load-page-dynamically.html" data-prefetch></a>
这种混合方法允许我们选择性地选择我们想要加载和缓存的链接。同样,这种模式只推荐用于访问非常频繁的页面,因为这种行为会触发一个额外的 HTTP 请求来动态加载页面。
Ajax 驱动的导航
在上面的多页面示例中(参见清单 2–3),我们看到了 jQuery Mobile 如何从一个内部页面导航到另一个页面。当多页面文档初始化时,两个内部页面都已经添加到 DOM 中,因此从一个内部页面到另一个内部页面的页面转换速度非常快。当从一页导航到另一页时,我们可以配置要应用的过渡类型。默认情况下,框架会对所有过渡应用一个"slide"
效果。我们将在本章的后面讨论过渡和可供选择的过渡类型。
`
当一个单页面过渡到另一个单页面时,导航模型是不同的。例如,我们可以将多页面中的联系页面提取到它自己的文件中(contact.html
)。现在我们的主页(hijax.html
)可以像普通 HTTP 链接引用一样访问联系人页面:
清单 2–4。【Ajax 导航(ch2/hijax.html
)
`
<a href="contact.html" data-role="button">Contact Us
当点击上面的“联系我们”链接时,jQuery Mobile 将按如下方式处理该请求:
图 2–4。 错误加载屏幕
$.mobile.changePage()
用法
论据
例#1:
`//Transition to the "contact.html" page.
$.mobile.changePage( "contact.html" );
Contact Us`
例 2:
`// Go to an internal "#contact" page with a reverse "pop" transition.
$.mobile.changePage( '#contact', { transition: "pop", reverse: true } );
例 3:
`/* Dynamically create a new page and open it */
// Create page markup
var newPage = $("
Hi
// Add page to page container
newPage.appendTo( $.mobile.pageContainer );
// Enhance and open new page
$.mobile.changePage( newPage );`
重要提示: Ajax 导航不会用于加载外部链接的情况:
`
<a href="multi-page.html" rel="external">Home
<a href="multi-page.html" target="_blank">Home`
在这些情况下,将进行正常的 HTTP 请求处理。此外,不会应用 CSS 过渡。如前所述,该框架能够通过将“from”和“to”页面动态加载到同一个 DOM 中,然后应用平滑的 CSS 过渡来实现平滑过渡。如果没有 Ajax 导航,转换将不会平滑,并且在转换过程中不会显示默认的加载消息($.mobile.loadingMessage
)。
配置 Ajax 导航
Ajax 导航是全局启用的,但是如果 DOM 大小是一个问题,或者如果您需要支持不支持哈希历史更新的特定设备,您可以禁用这个特性(参见下面的注释)。默认情况下,jQuery Mobile 将为我们管理 DOM 大小或缓存,只将活动页面转换中涉及的“from”和“to”页面合并到 DOM 中。要禁用 Ajax 导航,请在绑定到 mobileinit 事件时设置$.mobile.ajaxEnabled = false。有关配置 jQuery Mobile 或管理 DOM 缓存的更多信息,请参考第八章。
注意: Ajax 导航已经在已知与哈希历史更新冲突的平台上被禁用。例如,jQuery Mobile 已经为黑莓 5、Opera Mini (5.0-6.0)、诺基亚 Symbian³ 和 Windows Phone 6.5 禁用了 Ajax 导航($.mobile.ajaxEnabled = false)
。当使用常规 HTTP 和整页刷新浏览时,这些设备更有用。
过渡
jQuery Mobile 在页面之间转换时有六种基于 CSS 的转换效果可供选择。默认情况下,框架会对所有过渡应用一个"slide"
效果。我们可以通过将data-transition
属性添加到任何链接、按钮或表单来设置替代转换:
<a href="dialog.html" **data-transition="slideup"**>Show Dialog</a>
过渡效果的完整列表在表 2–1 中描述:
从页面到页面的转换过程按以下步骤进行:
图 2–5。 第一步:点击按钮导航到另一个页面
图 2–6。 第二步:框架并排加载下一页
图 2–7。 第三步:框架转换到下一页
图 2–8。 第四步:过渡完成
提示:你可以通过在链接中添加data-direction="reverse"
来设置“向后”过渡。向前的"slide"
转换将向左滑动,相反,反向的"slide"
转换将向右滑动。例如,当转换回历史时,默认情况下会应用反向转换。但是,如果您的标题上有一个“主页”链接,您将需要应用 data-direction="reverse"
属性,否则将出现默认的“转发”效果:
<a href="home.html" data-icon="home" data-iconpos="notext" **data-direction="reverse"** class="ui-btn-right jqm-home"> Home </a>
对话框
对话框类似于页面,除了它们的边框是内嵌的,给它们一个模态对话框的外观。jQuery Mobile 在设计对话框样式方面非常灵活。我们可以创建确认对话框(见图 2–9)、警告对话框(见图 2–10),甚至行动单样式的对话框(见图 2–11、图 2–12)。
图 2–9。 确认对话框(ch2/dialog.html
)
图 2–10。 警报对话框(ch2/alert.html
)
我们可以在链接或页面组件上将页面转换成对话框。在一个链接上,添加如清单 2–5 所示的data-rel="dialog"
属性。添加该属性将自动加载目标页面,并将其增强为模式对话框。
清单 2–5。 链路级转换
`
<a href="#terms" data-rel="dialog" data-transition="slidedown">Terms
Terms and Conditions
Do you agree to these terms?
Disagree
Agree
我们还可以在页面容器中配置对话框。将data-role="dialog"
属性添加到页面容器中,当组件加载时,它将被增强为一个模态对话框(参见清单 2–6)。
清单 2–6。ch2/dialog.html
页面级转换
`
Terms and Conditions
Terms and Conditions
Do you agree to these terms?
Disagree
Agree
注意:任何带有data-rel="dialog"
的链接或者任何带有data-role="dialog"
的页面都不会出现在历史中,也不能被书签标记。例如,如果您导航到一个对话框,关闭该对话框,然后点击浏览器的前进按钮,您将不会前进到该对话框,因为它将不存在于历史中。
链接对比页面配置
有两个打开对话框的选项,我们应该选择哪一个?我更喜欢页面配置(data-role="dialog"
),因为它允许我们在页面容器中配置一次对话框,导航到对话框的按钮不需要任何修改。例如,如果我们有三个按钮链接到我们的对话框,基于页面的配置只需要一个修改。而基于链接的配置需要三次更改,每个按钮一次。
jQuery Mobile dialog API 还公开了一个close
方法,您可以在以编程方式处理对话框时利用它。例如,如果我们想以编程方式处理图 2–9 中“同意”按钮的处理,我们可以处理点击事件,处理任何必要的业务逻辑,并在完成时关闭对话框:
`function processAgreement(){
// Save the agreement...
// Close the dialog
$('.ui-dialog').dialog('close');
}`
行动表
除了传统的对话框,我们还可以将对话框设计成行动表(参见图 2–11 和图 2–12)。只需移除标题,添加小的样式更新(见清单 2–7),你的对话框就会显示为一个动作表。行动表通常用于征求用户的回应。为了获得最佳用户体验,建议对动作表使用slidedown
过渡。方便的是,当对话框关闭时,它们会自动应用反向转换。例如,当您关闭此动作表时,将应用反向slideup
转换。
图 2-11。 动作表#1 ( ch2/action-sheet1.html
)
图 2–12。 动作表#2 ( ch2/action-sheet2.html
)
清单 2–7。 动作单(ch2/action-sheet1.html
)
`
<a href="#logout" data-transition="slidedown">Logout
Yes, I'm Sure!
No Way!
这也是我们第一次接触到数据主题属性。我们可以简单地用这个属性为所有 jQuery Mobile 组件添加对比和样式。在我们的对话框例子中,我们可以设置背景和按钮的主题。当设计对话框按钮时,通常会对比取消和动作按钮的风格。jQuery Mobile 中的主题在第七章中有更深入的讨论。
对话框 UX 指南
设计 UI 组件时,一致性是最重要的设计目标。关于特定对话指南,苹果手机界面指南 4 中的一些提示包括:
提示:对话框的最大宽度默认设置为 500 像素。这将在较小的移动显示器上全屏显示,并在桌面和平板电脑屏幕上显示 500 像素宽。如果您需要覆盖默认宽度,请在您的主题中使用以下 CSS:
ui-dialog .ui-header, .ui-dialog .ui-content, .ui-dialog .ui-footer { max-width: 100%; }
警报:
行动表:
4 见developer . apple . com/library/IOs/documentation/user experience/conceptual/mobile hig/mobile hig . pdf
。
有媒体查询的响应式布局
要使用 jQuery Mobile 创建响应式设计,建议利用 CSS3 媒体查询的强大功能。 5
`@media (orientation: portrait) {
/* Apply portrait orientation enhancements here... */
}
@media (orientation: landscape) {
/* apply landscape orientation enhancements here... */
}`
在某些情况下,jQuery Mobile 会为您创建响应式设计。下图显示了 jQuery Mobile 的响应式设计在纵向和横向模式下对表单字段定位的表现。例如,在纵向视图中(参见图 2–13),标签位于表单字段上方。或者,在横向重新定位设备时(参见图 2–14),表单域和标签并排出现。这种响应式设计基于设备可用的屏幕空间提供了最有用的体验。jQuery Mobile 为您提供了许多这些好的 UX 原则!
5 见www . w3 . org/tr/CSS 3-mediaquiries/
。
图 2–13。 (肖像)
图 2–14。 (风景)有求必应
警告:如果你在 iOS 中启动图 2–14(ch2/responsive.html
)并切换到横向,你可能已经注意到了移动 Safari 中的 iOS 缩放问题。 6 "当 meta viewport 标签设置为content="width=device-width, initial-scale=1"
或任何允许用户缩放的值时,将设备更改为横向会导致页面缩放大于 1.0。因此,页面的一部分被从右边裁剪掉,用户必须双击(有时不止一次)才能让页面正确缩放到视图中。”
在 Mobile Safari 解决此问题之前,您有几个选项可以解决此问题:
6 见【http://filamentgroup.com/examples/iosScaleBug/】的。
7 见adaptio . com/journal/4470/
。
在上面的例子中(参见图 2–13),jQuery Mobile 能够通过利用最小-最大宽度媒体特性来应用响应式设计。例如,当浏览器支持大于 450 像素的宽度时,表单元素浮动在其标签旁边。支持文本输入行为的 CSS 如下所示:
`label.ui-input-text {
display: block;
}
@media all and (min-width: 450px){
label.ui-input-text { display: inline-block; }
}`
重要提示:Windows Phone 7(Internet Explorer 8 及以下版本)不支持媒体查询。如果你想在不支持媒体查询的浏览器上支持响应式设计,建议利用 respond . js .8respond . js 为不支持媒体查询的浏览器提供媒体查询支持。
还有一组有限的特定于 Webkit 的媒体扩展,您可能会觉得有用。例如,要为配有高清 retina 显示屏的新款 iOS 设备应用 CSS 增强功能,您可以使用webkit-min-device-pixel-ratio
媒体功能:
//Webkit-specific media query for the iOS high-resolution Retina display @media screen and **(-webkit-min-device-pixel-ratio: 2)**{ // Apply retina display enhancements }
作为对 iOS 用户的额外奖励,jQuery Mobile 包含了一整套针对 retina 优化的图标,可以自动应用于任何具有非常高分辨率显示屏的 iOS 设备。
注意:如果你选择在单独的文件中分离特定于媒体的样式,你可以用 HTML <链接>媒体属性来引用它们。这种做法促进了关注点的良好分离,但是从性能的角度来看,这是因为每个单独的文件都需要一个额外的 HTTP 请求:
`
`8 见【https://github.com/scottjehl/Respond】??。
总结
在这一章中,我们回顾了 jQuery Mobile 的基础知识,并了解了如何快速启动和运行 jQuery Mobile 应用。我们回顾了两种 jQuery Mobile 页面模板,并讨论了它们在性能和导航流程方面的优势。我们还看了一下 jQuery Mobile 如何将我们的语义标记增强为优化的移动体验。此外,我们回顾了所有可用的页面转换,并讨论了每种转换的常见使用模式。最后,我们看到了许多不同的对话框样式来创建一个有效的界面,用于通知用户或从用户那里收集反馈。在第三章中,我们将进一步了解 jQuery Mobile 的导航,以及如何最好地利用页眉和页脚控件来管理我们的移动应用数据。
三、使用标题、工具栏和标签栏导航
所有移动应用都需要工具栏来帮助导航或管理屏幕上的数据。在本章中,我们将回顾提供这些特性的 jQuery Mobile 组件。主要组件是页眉和页脚。标题通常用于显示页面标题,并且可以选择包含控件来帮助导航或管理屏幕上的对象。页脚的设计类似于页眉,但它们的职责通常由工具栏或选项卡栏来管理。此外,我们将发现分段控件的功能。分段控件是一种特殊的控件,我们可以将其放置在页眉或页脚中,以帮助显示数据的可选视图。我们将探索每一个组件,并演示如何用文本、标准图标甚至自定义图标来设计它们的样式。
标题栏
标题栏显示当前屏幕的标题。此外,您可以添加用于导航的按钮,或者添加管理页面中各项的控件。虽然页眉是可选的,但它通常用于为活动页面提供标题。让我们从查看标题结构开始,看看如何向标题添加额外的控件来帮助管理页面上的项目。
页眉基础
关于标题有几点很重要。它们包括:
提示:您也可以使用表头作为分段控件,如图图 3–5 所示。分段控件允许用户显示相关数据的不同视图。
表头结构
页眉的基本用途是简单地显示活动页面的标题。最简单形式的标题如下所示。
`<div data-role="header">
Header Title
`表头定位
有三种样式可用于定位页眉。它们包括:
注意:为了实现真正的固定工具栏,浏览器需要支持位置:固定或溢出:自动。幸运的是,WebKit (iOS5)的新版本开始支持这种行为。在 jQuery Mobile 中,我们可以通过将touchOverflowEnabled
配置选项设置为 true 来启用这种行为(参见第八章的中的“可配置的 jQuery Mobile 选项”了解更多细节)。
清单 3–1。 【全屏(ch3/position-fullscreen.html
)
`<div data-role="page" data-fullscreen="true">
<div data-role="header" data-position="fixed">
Header
<div data-role="footer" data-position="fixed">
Footer
`
图 3–1。 全屏
图 3–2。 全屏显示,页眉页脚响应灵敏
注意:在 iOS 和 Android 中查看 jQuery Mobile 页面时,浏览器的地址栏会被隐藏。这是一个方便的功能,允许用户查看更多可用的屏幕空间,并平滑过渡。但是,如果您需要查看地址栏,向下拖动页面,地址栏将变得可见。
标题按钮
有些情况下,您需要在标题中添加控件来帮助管理屏幕内容。例如,“保存”和“取消”按钮是编辑数据时可用的常见控件。有三种样式的按钮可以添加到标题中。它们包括:
带文字和图标的按钮
在图 3–3 中,我们有一个带有“取消”和“完成”按钮的标题来帮助管理电影评论的条目。如清单 3–2 所示,按钮被设计成普通链接。我们还为每个按钮附加了一个带有data-icon
属性的图标。要创建纯文本按钮,只需删除data-icon
属性。在标题中,按钮是根据它们的语义顺序来定位的。例如,第一个按钮左对齐,第二个按钮右对齐。如果你的标题只包含一个按钮,你可以通过添加class="ui-btn-right"
到按钮的标记来右对齐按钮。
清单 3–2。 【页眉按钮】(ch3/header-buttons.html
)
`
Cancel
Add Review
Done
图 3–3。 带按钮的表头
只有图标的按钮
jQuery Mobile 包括几个标准图标(见表 4-1 ),你可以用它们来创建纯图标按钮。例如,"info"
图标通常与"flip"
转换一起使用,以显示配置选项或更多信息。使用标准图标消耗很少的空间,并且它们的含义在所有设备上相对一致。例如,如果我们想在现有列表中添加一个条目,我们可以选择显示一个"plus"
图标,允许用户在列表中添加条目(见图 3–4)。在这个例子中,我们有一个电影评论列表,用户可以点击“add
”图标来创建他们的评论。要创建一个只有图标的按钮,需要两个属性,如清单 3–3 所示。
清单 3–3。 【标题与图标(ch3/header-icons.html
)
`
Reviews
<a href="#" data-icon="plus" data-iconpos="notext" class="ui-btn-right">
图 3–4。 带图标的表头
带有分段控件的标题栏
分段控件是一组内嵌控件,每个控件显示不同的视图。例如,图 3–5 中的分段控件按特定类别显示电影。这种分段控制允许用户根据他们选择的类别快速观看电影:在影院,即将上映,或顶级。
图 3–5。 分段控制
建议将分段控件放置在主标题内,如清单 3–4 所示。如果您选择将标题定位为固定控件,这种定位允许分段控件与主标题无缝集成。通过增加一些小的样式更新,我们现在有了一个分段的控件,允许用户在不同的视图中快速查看数据!
清单 3–4。 【分段控制】ch3/header-segmented-control.html
<div data-role="header" data-theme="b" data-position="fixed"> <h1>Movies</h1> <div class="segmented-control ui-bar-d">
`
`
固定截断的页眉或页脚...
jQuery Mobile 将截断带有长标题的页眉和页脚(参见图 3–6)。当文本太长时,jQuery Mobile 会截断文本并在末尾添加省略号。如果您遇到这种情况,并且想要显示完整的文本(参见图 3–7,您可以调整 CSS 选择器来解决这个问题,如清单 3–5 所示。
清单 3–5。 截断修罗(ch3/truncation-fixed.html
)
.ui-header .ui-title, .ui-footer .ui-title { **margin-right: 0 !important; margin-left: 0 !important;** }
图 3–6。 截断发行
图 3–7。 截断修复
后退按钮
后退按钮(见图 3–8)会在 UX 设计师中引起激烈的争论。我们应该添加自己的后退按钮,还是应该利用一些设备和所有浏览器上可用的硬件/软件后退按钮?幸运的是,jQuery Mobile 为您提供了全局自动启用或禁用它们的选择。您还可以选择逐页添加或删除它们。
图 3–8。 后退按钮必须明确启用。
默认情况下,jQuery Mobile 中的后退按钮是禁用的。如果您需要 back 按钮出现在页眉中,您有几个选项来添加它们:
`
// Globally enable the back button, set the default back button text,
// and set back button theme
\((document).bind('mobileinit',function(){
**\).mobile.page.prototype.options.addBackBtn = true;**
\(.mobile.page.prototype.options.backBtnText = "Previous";**
**\).mobile.page.prototype.options.backBtnTheme = "b";
});`
此外,如果您全局启用了后退按钮,您可以通过在页面标题上添加data-add-back-btn="false"
属性来选择禁用特定页面上的后退按钮。这将从特定页面的页眉中删除“后退”按钮。
`
提示:虽然后退按钮在所有的移动浏览器中都可用,但是在 jQuery Mobile 中有一些特殊情况下,您可能需要后退按钮或替代导航:
建议所有页面都包含一个返回主屏幕的链接,无论是通过链接的徽标还是主页按钮。目标是永远不要让用户陷入导航流程的死胡同。当用户访问深层链接或书签页面时,可能会出现一种常见的情况。如果你唯一的导航机制是后退按钮,并且历史堆栈是空的,那么自动后退按钮将不会出现,让用户陷入死胡同。因此,在标题栏的右侧包含一个主页图标链接是一个非常好的做法。
在设计 PhoneGap 集成时,如果您的目标操作系统不支持基于硬件的导航,如 iOS 或 WebOS,您需要考虑使用后退按钮。
回溯链接
如果你想创建一个行为类似后退按钮的按钮,你可以添加data-rel="back"
到任何锚元素:
<a href="home.html" **data-rel="back"** data-role="button">Go Back</a>
使用data-rel="back"
,链接将模仿后退按钮,后退一个历史条目(window.history.back()
),并忽略链接的默认 href。对于 C 级浏览器或不支持 JavaScript 的浏览器,data-rel
将被忽略,而href
属性将作为后备。
页脚栏
页脚组件与页眉组件几乎相同,只有很小的不同。主要的区别是页脚在按钮的放置上更加灵活。例如,当处理标题时,第一个按钮左对齐,第二个按钮右对齐。页脚将其按钮从左到右按顺序内联放置。这种灵活性允许我们将页脚设计成工具栏或标签栏。我们将看到两者的例子,但首先让我们从基础开始。
页脚基础知识
页脚有几点很重要。它们包括:
页脚结构
最简单的页脚如下面的代码所示。data-role="footer"
是唯一必需的属性。在页脚中,您可以包含任何语义 HTML。页脚通常用于包含工具栏和选项卡控件。工具栏提供了一组用户可以在当前上下文中执行的操作。选项卡栏让用户能够在应用的不同视图之间切换。
`<div data-role="footer">
提示:要将页脚定位在屏幕的最底部,向页脚元素添加data-position="fixed"
。默认页脚位于内容之后,而不是屏幕的底部边缘(参见图 3–9)。例如,如果你的内容只占了屏幕高度的一半,页脚就会出现在屏幕的中间。我们可以通过向页脚元素添加data-position="fixed"
来将页脚定位在屏幕的底部。
<div data-role="footer" **data-position="fixed"**>
图 3–9。 默认页脚位置
页脚定位
页眉的三种定位样式也适用于页脚。它们包括:
页脚按钮
有三种样式的按钮可以添加到页脚。它们包括:
-
只有文本的按钮。这种风格的按钮在工具栏中工作良好,因为工具栏的外观没有选项卡栏大。页脚中的普通链接将显示为纯文本按钮:
<a href="#">Sync</a>
-
A button with only an icon. This style of button also works well within a toolbar. An icon-only button requires the addition of two attributes,
data-icon
anddata-iconpos="notext"
:<a href="#"
data-icon = " plus " data-iconpos = " notext "> -
关于
data-icon
值的完整列表,请参考表 4-1 。 -
带有文本和图标的按钮。这种风格的按钮在标签栏中工作良好:
Home
提示: jQuery Mobile 是一个优秀的框架,用于构建能够在移动、平板和桌面浏览器上响应显示的应用。虽然页眉和页脚组件在移动设备上提供了一种“原生”的感觉,但在桌面上看时,它们的翻译效果很差。如果您的 jQuery Mobile 应用针对不同的浏览器大小,您可能希望省略页眉和页脚组件。或者,您可能会发现直接在内容部分中添加自定义页眉或页脚标记更为有益。
工具栏
工具栏有助于管理当前屏幕的内容。例如,邮件应用经常使用工具栏来帮助管理你的电子邮件。在用户需要执行与当前屏幕上的对象相关的操作的情况下,工具栏提供了有用的体验。构建工具栏时,我们可以选择使用图标或文本。在下面的例子中,我们将看到工具栏的例子,其中包含了图标、文本和分段控件样式的按钮。
带图标的工具栏
只有图标的工具栏是最常见的。它们的主要优势是,与文本相比,它们占用的屏幕空间更少。选择图标时,重要的是选择表达清晰含义的标准图标。在图 3–10 中,我们有一个显示电影评论的屏幕。为了帮助用户管理评论,我们还包括了一个带有标准图标的工具栏。工具栏允许用户执行五个
图 3–10。 带有标准图标的工具栏可能的操作:
- Navigate to pre-audit.
- Reply and comment.
- Mark comments as favorites.
- Add a new comment to the movie.
- Navigate to the next comment.
创建工具栏需要最少的标记(见清单 3–6)。我们只需要一个无序的按钮列表,用data-role="navbar"
属性包装在一个 div 中。工具栏按钮是灵活的,将根据设备的宽度均匀分布。在这个例子中,我们使用了 jQuery Mobile 标准可用图标套件中的图标(参见表 4-1 )。
清单 3–6。 工具栏(ch3/toolbar-icons-standard.html
)
`
`提示:如果你想在导航条上添加耀斑,那么导航条组件同样可以很好地与自定义图标配合使用!如果对自定义图标解决方案感兴趣,我们将在清单 3–10 中演示该解决方案。
带有分段控件的工具栏
您还可以在工具栏中放置一个分段控件,使用户可以访问应用数据的不同视角或不同的应用视图。在 Figure 3–11 中,我们将分段控件放置在工具栏中,以允许用户显示他们日历数据的不同视图。您可能已经注意到,这个分段控件(参见清单 3–7)与我们的标题示例中显示的分段控件示例相同。我们可以在页眉和页脚组件中重用分段控件。分段控件只是一组包装在控件组中的按钮,并根据您的需要进行样式化。在下一节中,我们将展示带有标签栏的分段控件的另一种用法!
图 3–11。 工具栏带分段控件
清单 3–7。 工具栏带有分段控件(ch3/toolbar-segmented-control.html)
`
标签栏
我们也可以将页脚设计成标签栏。选项卡栏使用户能够在应用的不同视图之间切换。如果你不太熟悉标签栏,它们的行为与你在网上找到的基于标签的导航非常相似。选项卡栏通常作为一个持久的页脚放置在屏幕的底部边缘,从应用的任何位置都可以访问它。为了清晰起见,标签栏通常包含同时显示图标和文本的按钮。在下面的例子中,我们将看看三种风格的标签栏。第一个选项卡栏示例将包括 jQuery Mobile 中已经提供的几个标准图标。其次,我们将看到一个使用自定义图标的标签栏示例。jQuery Mobile 可以方便地集成您选择的自定义图标。最后,我们将在同一个 UI 中组合标签栏和分段控件,以允许用户在同一个屏幕上导航和查看不同形式的数据。
带有标准图标的标签栏
最简单的标签栏解决方案(参见图 3–12)是使用 jQuery Mobile 的标准图标集,如清单 3–8 中所详述。关于标准 jQuery Mobile 图标的完整列表,请参考表 4-1 。如果你使用这些标准图标,你的标签栏就不需要额外的样式。
图 3–12。 带标准图标的标签栏
清单 3–8。 带标准图标的标签栏(ch3/tabbar-icons-standard.html
)
`
- Home
- Movies
- Theatres
持久标签栏
为了使我们的标签栏持久,我们需要添加一个额外的属性到页脚。为了在页面转换过程中保持页脚的持久性,将data-id
属性添加到每个选项卡栏的页脚,并将它们的值设置为相同的标识符。例如,在清单 3–9 中,每个标签栏都包含一个标识符data-id="main-tabbar"
。有了这项新增功能,您的标签栏将在过渡期间保持不变。例如,如果我们点击一个不活动的标签栏,屏幕会“滑动”,而标签栏在转换过程中保持固定不变的状态。此外,当从一个选项卡转换到另一个选项卡时,为了保持每个选项卡栏的活动状态,添加一个类ui-state-persist
和ui-btn-active
。下面突出显示了持久选项卡栏的标记。
清单 3–9。 持久标签栏
`
`标签栏带有自定义图标
想在标签栏或工具栏上添加自定义图标吗?jQuery Mobile 支持添加自定义图标,只需要很少的标记。例如,在下面的标签栏示例中(参见图 3–13),我们包含了来自 Glyphish 的几个第三方图标。 1
图 3–13。 带自定义图标的标签栏
为了支持自定义图标的添加,我们需要添加data-icon="custom"
属性、一些用于定位的自定义样式,以及将每个按钮与其样式相关联的 id 引用。下面的清单 3–10 重点介绍了这些新增内容。
1 见[
glyphish.com/](http://glyphish.com/)
。图标由 Joseph Wain 创作,并根据知识共享署名 3.0 美国许可证进行许可。
提示:这个自定义图标解决方案同样适用于工具栏。事实上,通过简单地删除按钮上的文本,就可以创建一个带有自定义图标的细长工具栏!
清单 3–10。 标签栏带有自定义图标(ch3/tabbar-icons-custom.html)
`
- Home
- Movies
- Theatres
带分段控件的标签栏
至此,我们已经看到了标签栏和分段控件的例子。把两者融合在一起怎么样!我们可以利用持久标签栏来帮助导航我们的站点,并且我们可以利用分段控件来显示我们数据的不同视图。在下面的示例中(参见图 3–14),我们创建了一个用户界面,允许用户在家庭、电影和剧院选项卡之间导航。当用户选择电影选项卡时,我们在标题中显示分段控件,以允许用户帮助过滤他们的电影列表。在本例中,我们完全删除了标题文本,因为活动选项卡突出显示了页面的标题。有关本示例的完整源代码列表,请参考 CH3/tabbar-and-segmented-control . html。
图 3–14。 带分段控件的标签栏
总结
在本章中,我们发现了 jQuery Mobile 中几乎所有可能的页眉和页脚组合。jQuery Mobile 有一组丰富的组件,可以极大地简化导航和数据管理需求。我们看到标签栏解决方案提供了在应用内不同视图之间切换的能力。我们回顾了几种有助于管理当前屏幕上的对象的工具栏配置。我们还添加了分段控件,让用户能够访问应用数据的不同视角。此外,每个组件的外观都很灵活。每个组件都是可主题化的,我们可以用图标、文本或者两者的组合来设计我们的按钮。在下一章中,我们将回顾所有可能的按钮样式选项,并看看我们可以在 jQuery Mobile 中用于基于表单的开发的组件。
四、表单元素和按钮
移动应用必须支持高效的用户体验。由于这个原因,很少看到有大量表单字段的移动应用。事实上,我们的应用对用户的要求越少,用户和应用的效率就越高。移动网络正在慢慢采用设备 API1,这些 API 允许开发者通过最少的用户交互来收集大量信息。例如,74%的移动开发者在他们的应用 2 中使用地理定位。地理定位允许我们通过简单的点击确认按钮来收集用户的国家、州、城市、邮政编码和地址信息。尽管这些设备 API 使用户体验更加高效,但对于设备不支持地理定位的用户来说,我们仍然需要用表单字段的传统方式来捕获数据。
在这一章中,我们将从最流行的移动用户界面组件开始,按钮。按钮的样式和配置方式有很多种。我们将会看到用文本、图标以及两者的组合来设计按钮的例子。
接下来,我们将详细了解每一个标准 HTML 表单组件,并确定它们能很好解决的常见用例。您会惊喜地发现每个表单组件都被 jQuery Mobile 自动优化了——这个特性可以方便地在所有设备上提供统一的用户体验。我们还将回顾每个表单元素特有的 jQuery Mobile 数据属性,并查看修改这些属性来配置和样式化表单的代码示例。此外,我们将回顾与每个表单组件相关联的插件,看看当用户需要更动态的体验时,我们如何利用插件 API 来动态地创建、增强和更新我们自己的组件。
1 见[
www.w3.org/2009/dap/](http://www.w3.org/2009/dap/)
。
2 见[
www.webdirections.org/sotmw2011/](http://www.webdirections.org/sotmw2011/)
。
最后,我们将探索Mobiscroll
插件的特性,它为日期选择器、搜索过滤器或自定义列表提供了一个优雅而灵活的界面。
按钮
按钮是移动应用中最常用的控件,因为它们提供了非常高效的用户体验。我们已经在很多例子中看到了按钮,包括对话框、动作表、分段控件和标题。jQuery Mobile 按钮有多种风格。我们有链接按钮、表单按钮、图像按钮、纯图标按钮以及文本和图标相结合的按钮。正如所料,jQuery Mobile 按钮的样式都是一致的。无论你有一个链接按钮还是一个基于表单的按钮,框架都会给它们相同的样式。在回顾这些按钮时,我们还将确定每种按钮的常见使用案例。
链接按钮
链接按钮是最常用的按钮类型。每当你需要将一个普通的链接设计成一个按钮时,给链接添加data-role=”button”
属性(参见 Figure 4–1)。
图 4–1。 链接按钮
默认情况下,页面内容部分中的按钮被设计为块级元素,因此它们将填充其外部容器的整个宽度。然而,如果你想要一个更紧凑的按钮,其宽度仅与里面的文本和图标一样,那么添加data-inline="true"
属性(参见清单 4–1)。
清单 4–1。 链接按钮(ch4/link-buttons.html)
<a href="#" **data-role="button"**>Link button</a> <a href=*"#"* **data-role=*"button"* data-inline=*"true"***>Disagree</a> <a href=*"#"* **data-role=*"button"* data-inline=*"true"***>Agree</a>
注意:如果你想让按钮并排放置,占据整个屏幕宽度,使用两列网格。我们将在第六章的中更详细地探讨灵活的网格布局。具体来说,对于 2 列网格布局,参考列表 6-2 。
表单按钮
基于表单的按钮(见清单 4–2)实际上比基于链接的按钮更容易设计,因为你不需要做任何修改。为了简单起见,框架会自动将任何button
或input
元素转换成一个移动样式的按钮(见图 4–2)。
清单 4–2。 表单按钮(ch4/form-buttons.html)
<button type="submit">Button element</button> <input type="button" value="button" /> <input type="submit" value="submit" /> <input type="reset" value="reset" />
图 4–2。 表单按钮
提示如果您想要禁用表单按钮或任何其他控件的自动初始化,您可以将data-role=”none”
属性添加到元素中,jQuery Mobile 不会增强该控件:
<button data-role=”none”>Button element</button>
图像按钮
将图像设计成按钮只需要您最少的努力。当用锚点标签包装图像时,不需要修改(参见图 4–3 和清单 4–3 中的相关代码)。但是,当将图像附加到输入元素时,您需要添加data-role="none"
属性。
图 4–3。 图像按钮
清单 4–3。 图片按钮(ch4/image-buttons.html)
<!-- Image buttons --> <input type="image" src="cloud.png" data-role="none" /> ![images](https://gitee.com/OpenDocCN/vkdoc-frontend-framework-zh/raw/master/docs/pro-jqmobi/img/U0401.jpg)
用图标设计按钮的样式
jQuery Mobile 包括一组在移动应用中常用的标准图标,其中包括一个白色图标精灵,该精灵在图标后面有一个半透明的黑色圆圈,以确保在任何背景颜色上都有良好的对比度(参见图 4–4)。
图 4–4。 带有标准图标的按钮
通过添加data-icon
属性并指定显示哪个图标,可以将图标添加到任何按钮上(参见清单 4–4)。
清单 4–4。 按钮带图标(CH4/icon-Buttons-standard . html)
<!-- Buttons with standard icons. Refer to Table 4-1 for icon list. --> <input type="button" value="Delete" **data-icon="delete"**/> <a href=*"#"* data-role=*"button"* **data-icon=*"plus"***>Button link</a> <button **data-icon=*"minus"***>Button element</button>
Table 4–1 包含每个data-icon
属性值及其对应的图标图像。除了data-icon="custom".
之外,每个属性值都有一个关联的图像,我们将在下一节看到一个与自定义图标集成的例子。
纯图标按钮
只有图标的按钮通常用在标题、工具栏和标签栏中,因为它们占用很少的空间(见 Figure 4–5)。
图 4–5。 图标按钮
在上一章中,我们看到了几个纯图标按钮的例子。我们最初在图 3-4 中看到一个"plus"
图标,允许用户点击“添加”图标来创建一个新的电影评论。我们还看到工具栏中使用的纯图标按钮(见图 3-10 )和标签栏(见图 3-12 )来帮助表达每个按钮的含义。要创建一个只有图标的按钮,将data-iconpos=”notext”
属性添加到按钮中(参见清单 4–5)。
清单 4–5。 图标专用按钮(ch4/icon-only-buttons.html)
<a href=*""* data-role=*"button"* data-icon=*"plus"* **data-iconpos=*"notext"***></a> <button data-icon=*"search"* **data-iconpos=*"notext"***>Search</button>
注意:每个白色图标后面的半透明黑色圆圈确保了在任何背景颜色上的良好对比度,并且与 jQuery Mobile 主题化系统配合良好。例如,在下图中,第一行中的图标采用 data-theme="a "样式,第二行中的图标采用 data-theme="c "样式。为了保持视觉一致性,建议创建一个 18 × 18 像素的白色图标,保存为 PNG-8,具有 alpha 透明度。
图标定位
默认情况下,图标是左对齐的(参见图 4–6)。然而,你可以通过添加按钮的data-iconpos
属性来明确地将图标对齐到任意一边,该属性的值对应于对齐的一边(参见清单 4–6)。
图 4–6。 图标定位
清单 4–6。 图标专用按钮(ch4/icon-positioning.html)
<a href=”#” data-role=*"button"* data-icon=*"arrow-u"***data-iconpos="top"**> <a href=*"#"* data-role=*"button"* data-icon=*"arrow-l"* **data-iconpos=”left”**> <a href=*"#"* data-role=*"button"* data-icon=*"arrow-r"* **data-iconpos=*"right"***> <a href=*"#"* data-role=*"button"* data-icon=*"arrow-d"* **data-iconpos=*"bottom"***>
带有自定义图标的按钮
还记得我们在图 3-13 中给我们的标签栏添加自定义的图形图标吗?我们可以以同样的方式将按钮与自定义图标集成在一起(参见图 4–7)。
图 4–7。 自定义图标
然而,通过按钮,我们可以应用一个更简单的解决方案,如清单 4–7 所示。向按钮添加自定义图标需要两个步骤:
- Add a
data-icon
attribute to the link. The value of this property must uniquely identify the custom icon. For example,data-icon=”my-custom-icon”.
- Create a CSS class property to set the background source for our custom image. The name of the property must be named ". ui-icon- 。 For example, if our data icon value is "
my-custom-icon
", our new CSS class attribute will be ".ui-icon-my-custom-icon
”。
清单 4–7。 自定义图标集成(CH4/icon-buttons-Custom . html)
<style> ** .ui-icon-custom1 {** background**:**url(data:image/png;base64,iVBORw0...)50% 50% no-repeat; background-size: 14px 14px; } </style> <a href="#" data-role="button" **data-icon="custom1"**>Custom</a>
提示:我们定制图像的背景源是用数据 URI 方案加载的。这可能是从外部加载小图像的一种高性能替代方法。例如,通过内嵌自定义图像,我们消除了一个 HTTP 请求。然而,这种技术的主要缺点是 base64 编码的字符串比原始图像大 1/3 倍。要查看完整的 base64 编码字符串,请参考 ch4/icon-buttons-custom.html 中的源代码清单。
分组按钮
到目前为止,所示的每个按钮示例都将每个按钮与其他按钮分开。但是,如果您想将按钮组合在一起,可以将按钮包装在一个控件组中。例如,我们在第三章中的分段控制示例就是这样分组的(参见图 4–8)。
图 4–8。 分组按钮
为了获得这种效果,将一组按钮包装在具有data-role=”controlgroup”
属性的容器中(参见清单 4–8)。
清单 4–8。 分组按钮(CH3/header-segmented-control . html)
`<div data-role="controlgroup" data-type="horizontal">
In Theatres
Coming Soon
Top Rated
默认情况下,框架会将按钮垂直分组,移除所有的边距,并在按钮之间添加边框。此外,为了在视觉上增强该组,第一个和最后一个元素将采用圆角样式。
因为默认情况下按钮是垂直放置的,所以我们可以通过添加data-type=”horizontal”
属性来设计它们的水平样式。与占用其外部容器整个宽度的垂直按钮不同,水平按钮只和其内容一样宽。
注意:水平分组按钮时,控件组宽度超出屏幕宽度时会换行。
主题按钮
像所有 jQuery Mobile 组件一样,按钮将从它们的父容器继承主题。此外,当你需要用不同的颜色设计按钮时,你可以将你选择的主题应用到任何添加了data-theme
属性的按钮上(参见清单 4–9)。
清单 4–9。 主题按钮(ch2/action-sheet2.html)
<a href="#home" data-role="button" **data-theme="b"**>YouTube</a> <a href="#home" data-role="button" **data-theme="b"**>Facebook</a> <a href="#home" data-role="button" **data-theme="b"**>Email</a> <a href="#home" data-role="button" **data-theme="c"**>Cancel</a>
例如,在我们的对话框和动作表示例中,我们根据第二章中的“对话框 UX 指南”来设计按钮,以提高可用性(参见图 4–9)。
图 4–9。 主题按钮
动态按钮
button
插件是自动增强原生按钮的小部件。我们可以利用这个插件来动态地创建、启用和禁用按钮。如果您需要在代码中动态创建按钮,有两个选项可用。您可以使用标记驱动的方法或者通过显式设置button
插件上的选项来动态创建按钮。
在标记驱动的解决方案中,我们为新按钮创建 jQuery Mobile 标记,将其附加到内容容器中,并对其进行增强(参见清单 4–10)。
清单 4–10。 创建带有标记驱动选项的动态按钮(ch4/dynamic-buttons.html)
`// Add link button to content container and enhance it
$( 'Star' )
.appendTo( “.ui-content” )
.button();
// Add form button after the first button and enhance it
$( '' )
.insertAfter( "#b1" )
.button();`
对于选项驱动的解决方案,我们创建一个本地链接,将按钮插入页面,然后应用我们的按钮增强(参见清单 4–11)。
清单 4–11。 创建带有插件驱动选项的动态按钮(ch4/dynamic-buttons.html)
// Create a new button, insert it after button 2, and enhance it. $**(** '<a href="#">Home</a>' **)** .insertAfter( “#b2” ) **.**button**({** 'icon'**:**'home'**,** 'inline'**:** true**,** 'shadow'**:** true**,** 'theme'**:** 'b' **})**;
在我们的最后一个例子中,我们创建了多个表单按钮,而不是为每个按钮单独调用button
插件,我们通过触发页面容器上的“create”
方法来增强它们(参见清单 4–12)。button
插件还公开了enable
和disable
方法,我们可以利用它们来动态启用和禁用按钮,如清单 4–12 所示。
清单 4–12。 创建按钮并动态禁用/启用按钮(ch4/dynamic-buttons.html)
`// Create multiple form buttons
\(( '<button id="button3">Button3</button>' ).insertAfter( “#button2” );
\)( '' ).insertAfter( “#button3” );
// Enhance all widgets on the page
$.mobile.pageContainer.trigger( "create" );
// Disable form button
$( “#button3” ).button( “disable” );
// Enable form button
$( “#button3” ).button( “enable” );`
提示:触发页面容器上的“create”方法会增强页面上的所有组件:$ . mobile . page container . trigger(" create ");当您需要一次增强多个页面组件时,这是一种方便的方法。
按钮选项
框架用来动态增强按钮的button
插件有以下选项:
**corners** *boolean*
**default:** true
默认情况下,按钮会有圆角。将此选项设置为 false 将删除圆角。该选项也作为数据属性公开:data-corners=”false”.
$( “#button1” ).button({ corners: false });
**icon** *string*
**default:** null
设置按钮的图标。该选项也作为数据属性公开:data-icon=”plus”.
$( “#button1” ).button({ icon: “home” });
**iconpos** *string*
**default:** “left”
设置图标位置。可能的值有:“left”, “right”, “top”, “bottom”,
和“notext”
。“notext”
值将把按钮显示为没有文本的纯图标按钮。该选项也作为数据属性公开:data-iconpos=”notext”.
$( “#button1” ).button({ iconpos: “notext” });
**iconshadow** *boolean*
**default: true**
如果为真,框架将为图标添加阴影。该选项也作为数据属性公开:data-iconshadow=”false”.
$( “#button1” ).button({ iconshadow: false });
**initSelector** *CSS selector string*
**default:** "button, [type='button'], [type='submit'], [type='reset'], [type='image']"
initSelector 用于定义选择器(元素类型、数据角色等。)用于触发widget
插件的自动初始化。例如,默认选择器匹配的所有元素都将被button
插件增强。要覆盖这个选择器,绑定到mobileinit
事件,并根据需要更新选择器:
$( document ).bind( "mobileinit", function(){ $.mobile.button.prototype.options.initSelector = "..."; });
**inline** *boolean*
**default:** false
如果设置为 true,这将使按钮显示为内嵌按钮。默认情况下,按钮将占用其容器的整个宽度。相比之下,内嵌按钮只占用文本的宽度。该选项也作为数据属性公开:data-inline=”true”.
$( “#button1” ).button({ inline: true });
**shadow** *boolean*
**default:** true
默认情况下,按钮会应用投影。将此选项设置为 false 将会移除投影。该选项也作为数据属性公开:data-shadow=”false”.
$( “#button1” ).button({ shadow: false });
按钮方法
button
插件有以下几种方法:
**enable**
:启用被禁用的按钮
$( "#button1" ).button( "enable" );
**disable**
:禁用一个按钮
$( "#button1" ).button( "disable" );
按钮事件
button
插件支持以下事件:
create
创建按钮时触发
创建自定义按钮时会触发此事件。它不用于创建自定义按钮。
$( '<a href="#" id="button2">Button2</a>' ) .insertAfter( "#button1" ) .button({ theme: 'a', create: function(event) { console.log( "Creating button..." ); } })
表格元素
jQuery Mobile 将增强所有原生表单元素,使它们在移动设备上更具吸引力和可用性。然而,不支持这些增强功能的旧浏览器将逐渐回归到原生元素,以保持可用的体验。
表格基础知识
在 jQuery Mobile 中构建基于表单的应用的方法与我们传统上在 Web 上构建表单的方法非常相似。尽管为了清楚起见,应该指定一个action
和method
属性,但它们不是必需的。默认情况下,action
默认为当前页面的相对路径,可以用$.mobile.path.get()
找到,未指定的method
默认为get
。
当提交表单时,它们会以默认的“slide”
转换方式转换到下一页。然而,我们可以用之前用来管理链接的相同数据属性来配置表单转换行为(参见清单 4–13)。
清单 4–13。 提交表格(ch4/form-request.html)
`<form action="/save.html" method="post" data-transition="pop">
<label for="email">Email:
<input type="email" name="email" id="email" value="" />
<button type="submit" name="submit">Submit
我们可以向表单元素添加以下属性来管理转换或禁用 Ajax:
data-transition=”pop”
data-direction=”reverse”
data-ajax=”false
注意:确保每个表单的id
属性在整个站点中是唯一的,这一点很重要。如前所述,在转换时,jQuery Mobile 会将“from”和“to”页面同时加载到 DOM 中,以完成平稳的转换。为了避免任何冲突,表单 id 必须是唯一的。
提示:在构建表单时,建议将每个表单字段与其对应的标签进行语义关联。标签的 for
属性和输入的 id
属性建立了这样的关系:
`<label for="name">Name:
<input type="text" name="name" id="name" value="" />`
该协会创建了辅助技术可访问的符合 508 的应用。政府或国家机构经常要求可访问性。您可以使用 WAVE 3 工具测试您的移动应用的兼容性。
文本输入
文本输入是移动设备上最麻烦的表单域。除非你是世界短信冠军,否则在物理或虚拟的 QWERTY 键盘上输入文本是低效的。这就是为什么自动收集尽可能多的用户信息是有价值的。如前所述,设备 API 可以帮助简化这种用户体验。尽管最小化这些繁琐的任务是一个好的目标,但有时我们必须通过文本输入收集用户反馈。最常见的文本表单字段如图 4–10 所示。
3 见[
wave.webaim.org/](http://wave.webaim.org/)
。
图 4–10。 文字输入
从开发人员的角度来看,我们可以创建 jQuery Mobile 表单和文本输入,而不需要额外的标记(参见清单 4–14)。可选地,我们可以为我们的文本输入选择一个合适的主题,方法是将data-theme
属性添加到 input 元素中,以增强表单字段的对比度。
清单 4–14。 文本输入(ch4/text-inputs.html)
<input **type="text"** name="text" value=”” id=”text” **placeholder="Text"**/> <input **type="number"** name="number" value="" id=”number” /> <input **type="email"** name="email" value="" id="email" data-theme=”d” /> <input **type="url"** name="url" value="" id="url" /> <input **type="tel"** name="tel" value="" id=”tel” /> <input **type=*"search"*** name=*"search"* value=*""* *id="search"* /> **<textarea** cols=*"40"* rows=*"8"* name=*"textarea"* id=*"textarea"*></textarea>
提示:要以一种可访问的方式隐藏标签,将 ui-hidden-accessible 样式附加到元素上。例如,我们将这种技术应用于图 4-10 中的搜索字段。这将优雅地隐藏标签,同时保持 508 合规性:
<label for="search" **class="ui-hidden-accessible"**>Search</label> <input type="search" id="search" placeholder="Search" />
构建表单时,将输入字段与其语义类型相关联是很重要的。这种联系有两个好处。首先,当输入字段获得焦点时,它会用适当的键盘提示用户。例如,指定为type=”number”
的字段将自动提示数字键盘(参见图 4–11)。同样,映射有type=”tel”
的字段将提示电话专用键盘(参见图 4–12)。
图 4–11。 数字键盘
图 4–12。 电话键盘
此外,该规范允许浏览器应用适用于字段类型的验证规则。提交表单时,浏览器对自动验证的支持仍然很少,但会随着时间的推移而改进。有关移动输入类型和属性的完整列表,请参考 Peter-Paul Koch 的“移动输入测试” 4 。它显示了所有可用的移动输入类型和属性及其相关的浏览器支持。
大多数移动浏览器都支持的另一个特性是placeholder
属性。该属性为文本输入添加一个提示或标签,当字段获得焦点时自动消失(参见清单 4–14)。
注意:搜索字段(type=”search”
)的样式和行为与其他输入类型略有不同。它包含一个左对齐的“搜索”图标,它的角是药丸形状,当用户输入文本时,一个“删除”图标将出现在右对齐的位置,以帮助清除字段。
动态文本输入
textinput
插件是自动增强文本输入和文本区域的小部件。我们可以利用这个插件来动态地创建、启用和禁用文本输入(参见清单 4–15)。
清单 4–15。 textinput 插件示例(ch4/dynmic-text-input.html)
`// Create text input with markup-driven options
$( '' )
.insertAfter( “#firstName” )
.textinput();
// Create text input with plugin-driven options
$( '' )
.insertAfter( “#text1” )
.textinput({
theme: 'c'
});
// Disable text input
$( “#text1” ).textinput( “disable” );
// Enable text input
$( “#text1” ).textinput( “enable” );`
4 见[
www.quirksmode.org/html5/inputs_mobile.html](http://www.quirksmode.org/html5/inputs_mobile.html)
。
文本输入选项
textinput
插件有以下选项:
**initSelector** *CSS selector string*
**default:** "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea"
initSelector 用于定义选择器(元素类型、数据角色等。)用于触发widge
t 插件的自动初始化。例如,默认选择器匹配的所有元素都将被textinput
插件增强。要覆盖这个选择器,绑定到mobileinit
事件,并根据需要更新选择器:
$( document ).bind( "mobileinit", function(){ $.mobile.textinput.prototype.options.initSelector = "..."; });
**theme** *string*
**default:** null. Inherited from parent.
为文本元素设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。默认情况下,如果没有显式设置,所有元素都将继承与其父容器相同的样本颜色。该选项也作为数据属性公开:data-theme=”a”.
$( “#text1” ).textinput({ theme: "a" });
文字输入方法
textinput
插件有以下方法:
**enable:**
启用一个禁用的文本输入或文本区。
$( “textarea” ).textinput( “enable” );
disable:
禁用一个 textinput 或 textarea。
$( “textarea” ).textinput( “disable” );
文本输入事件
textinput
插件支持以下事件:
**create** *triggered when a text input is created*
创建自定义文本输入时触发此事件。它不用于创建自定义输入。
$( '<input type="text" name="text2" id="text2" value="" />' ) .textinput({ theme: 'c', create: function(event) { console.log( "Creating text input..." ); } }) .insertAfter( “#text1” );
选择菜单
jQuery Mobile framework 将自动增强所有本地 select 元素,不需要额外的标记(参见清单 4–16)。
清单 4–16。 原生选择菜单(CH4/select-menu-Native . html)
<label for="genre">Genre:</label> <select name="genre" id="genre"> <option value="action">Action</option> <option value="comedy">Comedy</option> <option value="drama">Drama</option> </select>
这个转换将用一个 jQuery Mobile 样式的按钮替换原来的 select,该按钮包含一个右对齐的向下箭头图标。默认情况下,点击此选择按钮将启动操作系统的本机选择选择器(参见图 4–13)。或者,正如我们将在下一节中看到的,我们可以配置 jQuery Mobile 来显示定制的选择菜单。
图 4–13。 选择菜单
用户做出选择后,选择按钮将显示所选选项的值。如果文本值对于按钮来说太大,文本将被截断,并显示一个尾随省略号。此外,在选择多个选项后,多选按钮将显示一个计数气泡或标记(参见图 4–13)。这是一种突出显示所选选项数量的视觉效果。
注意:在创建带有multiple="multiple"
属性的选择菜单时,一些移动平台不支持多选功能。因此,建议在必要时使用自定义菜单。
自定义选择菜单
作为本地呈现选项列表的替代,我们可以选择在自定义 HTML/CSS 视图中呈现我们的选择菜单(参见图 4–14)。
图 4–14。 自定义选择菜单
对于这个视图,向 select 元素添加一个data-native-menu="false"
属性(参见清单 4–17)。
清单 4–17。 自定义选择菜单(ch4/select-menu-cstom.html)
<label for="genre">Genre:</label> <select name="genre" id="genre" **data-native-menu="false"** data-theme=”a”> <option value="">Select one...</option> <option value="action">Action</option> <option value="comedy">Comedy</option> <option value="drama">Drama</option> </select>
下面列出了客户优势与本地优势的对比。
定制优势:
- 为所有设备提供统一的用户体验。
- 自定义菜单为多选选项列表提供了通用支持。
- 添加了一种处理占位符选项的优雅方式。我们将在下一节回顾占位符选项。
- 自定义菜单是可主题化的(参见清单 4–17)。
定制缺点:
- 不如本地呈现的选择菜单性能好。当比较包含许多选项的菜单时,这一点会更加明显。
注意:你也可以利用Mobiscroll
5 插件作为定制选择菜单的另一种选择。在本章的最后,我们包括了这个插件的几个例子,因为我们演示了它的日期选择器和搜索过滤器的用法。
占位符选项
占位符是自定义选择菜单独有的功能。占位符有三个好处:
- 占位符要求用户做出选择。默认情况下,如果没有配置占位符,将选择列表中的第一个选项。
- 占位符可用于显示未选中选择按钮的提示文本(参见图 4–14)。例如,未选中的票据交付字段显示为占位符文本“选择一个...”。
- 显示选项列表时,一个占位符也作为标题出现(参见图 4–14)。
5 见[
code.google.com/p/mobiscroll/](http://code.google.com/p/mobiscroll/)
。
我们可以通过三种方式配置占位符:
- 我们可以向没有值的选项添加文本。
<option value="">Select one...</option>
- 当选项包含文本和值时,我们可以将
data-placeholder=”true”
属性添加到选项中:
<option value="null" data-placeholder="true">Select one...</option>
- 当您想使该字段成为没有提示文本或标题的必填字段时,请使用空选项:
<option value=""></option>
动态选择菜单
selectmenu
插件是自动增强选择菜单的小部件。有了这个插件,我们可以动态地创建、启用、禁用、打开和关闭选择菜单(参见清单 4–18)。
清单 4–18。 动态选择菜单(CH4/Dynamic-select-menu . html)
`// Create select menu with markup-driven options
$( '' )
.insertAfter( “#foo” )
.selectmenu();
// Create select menu with plugin-driven options
$( '' )
.insertAfter( “#select1” )
.selectmenu({
theme: "e",
overlayTheme: "c",
disabled: false,
nativeMenu: false
});`
选择菜单选项
selectmenu
插件有以下选项:
**corners** *boolean*
**default:** true
与其他按钮类型一样,默认情况下,选择菜单按钮具有圆角。将此选项设置为 false 将删除圆角。该选项也作为数据属性公开:data-corners=”false”.
$( “#select1” ).selectmenu({ corners: false });
**disabled** *boolean*
**default:** false
禁用元素。selectmenu
插件也有enable
和disable
方法来动态启用和禁用控件。
$( “#select1” ).selectmenu({ disabled: true });
**hidePlaceholderMenuItems** *boolean*
**default:** true
默认情况下,当选择菜单打开时,占位符菜单项将从视图中隐藏。要使占位符项可选,请将该值设置为 false。
$( “#select1” ).selectmenu({ hidePlaceholderMenuItems: false });
**icon** *string*
**default:** “arrow-d”
设置选择按钮的图标。该选项也作为数据属性公开:data-icon=”plus”.
$( “#select1” ).selectmenu({ icon: “plus” });
**iconpos** *string*
**default:** “right”
设置图标位置。可能的值有:“left”, “right”, “none”,
和“notext”.``“notext”
值将选择显示为一个只有图标的按钮,没有占位符文本。“none”
值将完全移除图标。这个选项也作为一个数据属性公开:data-iconpos=”none”.
$( “#select1” ).selectmenu({ iconpos: “notext” });
**iconshadow** *boolean*
**default:** true
如果为真,框架将为图标添加阴影。该选项也作为数据属性公开:data-iconshadow=”false”.
$( “#select1” ).selectmenu({ iconshadow: false });
**initSelector** *CSS selector string*
**default:** "select:not(:jqmData(role='slider'))"
initSelector 用于定义选择器(元素类型、数据角色等。)来触发widget
插件的自动初始化。例如,默认选择器匹配的所有元素都将被selectmenu
插件增强。要覆盖这个选择器,绑定到mobileinit
事件,并根据需要更新选择器:
$( document ).bind( "mobileinit", function(){ $.mobile.selectmenu.prototype.options.initSelector = "..";
});
**inline** *boolean*
**default:** false
如果设置为 true,这将使选择按钮显示为内嵌按钮。默认情况下,选择按钮将占用其容器的整个宽度。相比之下,内嵌按钮只占用占位符文本的宽度。这个选项也公开为一个数据属性:data-inline=”true”
。
$( “#select1” ).selectmenu({ inline: true });
**nativeMenu** *boolean*
**default:** true
默认情况下,选择按钮将启动操作系统的本机选择选择器。要在自定义 HTML/CSS 视图中呈现选择菜单,请将该值设置为 false。该选项也作为数据属性公开:data-native-menu=”false”.
$( “#select1” ).selectmenu({ nativeMenu: false });
**shadow** *boolean*
**default:** true
默认情况下,选择按钮将应用投影。将此选项设置为 false 将会移除投影。该选项也作为数据属性公开:data-shadow=”false”.
$( “#select1” ).selectmenu({ shadow: false });
**theme** *string*
**default:** null. Inherited from parent.
设置元素的主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。默认情况下,这将继承与其父容器相同的样本颜色。该选项也作为数据属性公开:data-theme=”a”.
$( “#select1” ).selectmenu({ theme: "a" });
选择菜单方式
selectmenu
插件有以下方法:
**enable:**
启用一个禁用的选择菜单
$( “#select1” ).selectmenu( “enable”);
**disable**
: 禁用选择菜单。
$( “#select1” ).selectmenu( “disable” );
**open**
: 打开一个关闭的选择菜单。此方法仅适用于自定义选择。
$( “#select1” ).selectmenu( “open” );
**close:**
关闭一个打开的选择菜单。此方法仅适用于自定义选择。
$( “#select1” ).selectmenu( “close” );
**refresh**
: 更新自定义选择菜单。
这将更新自定义选择菜单,以反映本地选择元素的值。例如,如果本地选择的 selectedIndex 被更新,我们可以调用“刷新”来重建自定义选择。如果传递一个 true 参数,可以强制进行刷新和重建。
`// Select the third menu option and refresh the menu
var myselect = $( "#select1" );
myselect[0].selectedIndex = 2;
myselect.selectmenu( "refresh" );
// refresh and rebuild the list
myselect.selectmenu( “refresh”, true );`
选择菜单事件
selectmenu
插件支持以下事件:
**create:**
创建选择菜单时触发
创建自定义选择菜单时会触发此事件。它不用于创建自定义元素。
$( '<select name="select2" id="select2">...</select>' ) ** .**insertAfter**(** “#select1”**)** .selectmenu**({** create**:** function**(**event**) {** console.log**(** "Creating select menu..." **);** **}** ** });**
单选按钮
单选按钮将用户的选择限制为单一项目(参见图 4–15)。例如,从几个选项中选择一个应用设置通常是通过单选按钮来完成的,单选按钮因其简单易用而受到青睐。用户可以点击单选按钮的任意位置进行选择,jQuery Mobile 将自动更新底层的表单控件。
图 4–15。 单选按钮
在清单 4-19 中,我们添加了三个额外的属性来帮助样式和定位我们的单选按钮。第一个属性,data-role=”controlgroup”,
用圆角优雅地将按钮组合在一起。第二个属性, data-type=”horizontal”,
覆盖默认的定位——垂直——并水平显示按钮。最后,我们为我们的按钮设置了主题。默认情况下,单选按钮将继承其父控件的主题。然而,如果你想为你的单选按钮应用一个替换主题,你可以将data-theme
属性添加到相应单选按钮的标签中。
清单 4–19。 水平单选按钮(ch4/radio-buttons.html)
`
`注意:如果水平单选按钮的容器不够宽,无法在一行中显示,它们将会换行。如果换行有问题,您可以减小字体大小:.ui-controlgroup-horizontal .ui-radio label **{**font-size: 13px !important;**}**
动态单选按钮
checkboxradio
插件是一个可重用的小部件,可以自动增强单选按钮和复选框。有了这个插件,我们可以动态地创建、启用、禁用和刷新我们的单选按钮(参见清单 4–20)。
清单 4–20。 动态单选按钮(CH4/Dynamic-radio-buttons . html)
`// Create radio buttons with markup-driven options
\(**(** '<fieldset data-role="controlgroup">
<legend>Map view:</legend>
<input type="radio" name="map" id="map1" value="Map" />
<label for="map1" data-theme="c">Map</label>...</fieldset>'**)**
** .**insertAfter**(** "#radio1" **);**
\).mobile.pageContainer.trigger( "create" );
// Create radio buttons with plugin-driven options
\(**(** '<fieldset data-role="controlgroup">
<legend>Map view:</legend>
<input type="radio" name="map" id="map1" value="Map" />
<label for="map1">Map</label>...</fieldset>' **)**
**.**insertAfter**(** "#radio1" **);**
\)( “#map1” ).checkboxradio({ theme: "e" });
\(**(** “#map2” **).**checkboxradio**({** theme**:** "e" **});**
\).mobile.pageContainer.trigger( "create" );`
复选框和单选按钮选项
checkboxradio
插件有以下选项:
**initSelector**
CSS 选择器字符串
**default:** "input[type='checkbox'],input[type='radio']"
initSelector 用于定义选择器(元素类型、数据角色等。)用于触发小部件插件的自动初始化。例如,默认选择器匹配的所有元素都将被checkboxradio
插件增强。要覆盖这个选择器,绑定到mobileinit
事件,并根据需要更新选择器:
$( document ).bind( "mobileinit", function(){ $.mobile.checkboxradio.prototype.options.initSelector = "..."; });
**theme** *string*
**default:** null. Inherited from parent.
为复选框或单选按钮设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。默认情况下,这将继承与其父容器相同的样本颜色。该选项也作为数据属性公开:data-theme=”a”.
$( “#element1” ).checkboxradio({ theme: "a" });
复选框和单选按钮方法
checkboxradio
插件有以下方法:
**enable:**
启用已禁用的复选框或单选按钮。
$(“#element1” ).checkboxradio( “enable” );
disable: disable a checkbox or radio button.
$( “#element1” ).checkboxradio( “disable” );
**refresh:**
更新自定义复选框或单选按钮
这将更新自定义复选框或单选按钮,以反映本地元素的值。例如,我们可以动态检查一个单选按钮并调用“refresh
”来重新构建增强的控件。
// Dynamically set a checkbox or radio element and refresh it. $( "#elem1" ).attr( "checked", true ).checkboxradio( "refresh" );
复选框和单选按钮事件
checkboxradio
插件支持以下事件:
**create:**
创建复选框或单选按钮时触发
创建自定义复选框或单选按钮时会触发此事件。它不用于创建自定义元素。
$( '#element1' ) .checkboxradio({ theme: "e", create: function(event) { console.log( "Creating new element..." ); } });
复选框
复选框是一种常见的表单控件,允许用户从许多选项的列表中选择多个值(参见 Figure 4–16)。用户可以点击复选框按钮的任意位置进行选择,jQuery Mobile 将自动更新底层的表单控件。
图 4–16复选框
样式和定位复选框的标记与我们之前用于单选按钮的标记相同(参见清单 4–21)。同样,我们添加了三个附加属性来帮助设置复选框的样式和位置。第一个属性data-role=”controlgroup”,
用圆角优雅地将复选框元素组合在一起。第二个属性data-type=”horizontal”,
覆盖按钮的默认垂直位置,并水平显示它们。最后,我们为我们的按钮设置了主题。默认情况下,复选框将继承其父控件的主题。然而,如果你想应用一个替换主题,你可以在相应复选框的标签上添加data-theme
属性。
清单 4–21。 横向复选框(ch4/checkboxes.html)
`<fieldset data-role="controlgroup" data-type="horizontal">
<label for="c1" data-theme=”c”>Action
<label for="c2" data-theme=”c”>Comedy
<label for="c3" data-theme=”c”>Drama
注意:如果水平复选框的容器不够宽,无法在一行中显示,它们将会换行。如果换行有问题,您可以减小字体大小:
.ui-controlgroup-horizontal .ui-checkbox label { font-size: 11px !important; }
动态复选框
同样,checkboxradio
插件是自动增强复选框和单选按钮的小部件。有了这个插件,我们可以动态地创建、启用、禁用和刷新我们的复选框(参见清单 4–22)。checkboxradio
插件的完整列表在“动态单选按钮”一节中已有记载。单选按钮和复选框可以重用相同的 API。
清单 4–22。 动态复选框(CH4/Dynamic-checkboxes . html)
`// Create checkboxes with markup-driven options
\(( '<fieldset data-role="controlgroup">
<legend>Genre:</legend>
<input type="checkbox" name="genre" id="c1" />
<label for="c1" data-theme="c">Action</label>...</fieldset>' )
.insertAfter( "#element1" );
\).mobile.pageContainer.trigger( "create" );
// Create checkboxes with plugin-driven options
\(( '<fieldset data-role="controlgroup">
<legend>Genre:</legend>
<input type="checkbox" name="genre" id="c3" />
<label for="c3">Action</label>...</fieldset>' )
.insertAfter( "#create-cb2" );
\)( '#c3' ).checkboxradio({ theme: "e" });
\(( '#c4' ).checkboxradio({ theme: "e" });
\).mobile.pageContainer.trigger( "create" );`
滑块
滑块是一种常见的表单控件,允许用户在最小和最大范围之间选择一个值(见图 4–17)。
图 4–17。 滑块
例如,在我们的例子中,我们用一个滑块来调整音量或亮度,以调整高低设置之间的范围。我们可以调整滑块的最小和最大边界,还可以设置它的默认值。用户可以通过滑动控件或在滑块的相应文本字段中输入值来调整滑块。如清单 4–23 所示,jQuery Mobile 不需要额外的标记来增强我们的滑块。任何带有type=”range”
的输入元素都会被自动优化。
清单 4–23。 滑块(ch4/slider.html)
<label for="volume">Volume:</label> <input type="range" name="volume" id="volume" value="5" min="0" max="9"/>
滑块由两个可主题化的组件组成。有被称为滑块的前景组件和被称为轨道的背景组件。这些组件中的每一个都可以单独设置主题。要主题化滑块,将data-theme=”a”
属性添加到input
元素中。此外,为了给音轨添加主题,将data-track-theme=”a”
属性添加到input
元素中:
<input type="range" name="brightness" id="brightness" min="0" max="10" **data-theme="b"** **data-track-theme="a"**/>
动态滑块
slider
插件是一个多用途的小工具,可以自动增强滑块和开关控制。有了这个插件,我们可以动态地创建、启用、禁用和打开开关控制(参见清单 4–24)。
清单 4–24。 动态滑块(ch4/dynamic-slider.html)
`// Create slider with markup-driven options
\(**(** '<label for="s1">Brightness:</label>
<input type="range" name="s1" id="s1" min=”0” max=”9” data-theme="d”/>'**)**
** .**insertAfter**(** "#element1" **);**
\)( "#s1" ).slider();
// Create slider with plugin-driven options
\(( '<label for="s1">Brightness:</label>
<input type="range" name="s1" id="s1" min="0" max="10" />' )
.insertAfter( "#create-s2" );
\)( "#s1" ).slider({
theme: "d",
trackTheme: "a",
disabled: false
});`
滑块选项
slider
插件有以下选项:
**disabled** *boolean*
**default:** false
禁用控件。slider
插件也有enable
和disable
方法来动态启用和禁用控件。
$( “#element1” ).slider({ disabled: true });
**initSelector**
CSS 选择器字符串
**default:** "input[type='range'], :jqmData(type='range'), :jqmData(role='slider')"
initSelector 用于定义选择器(元素类型、数据角色等。)来触发widget
插件的自动初始化。例如,默认选择器匹配的所有元素都将被 slider
插件增强。要覆盖这个选择器,绑定到mobileinit
事件,并根据需要更新选择器:
$( document ).bind( "mobileinit", function(){ $.mobile.slider.prototype.options.initSelector = "...";
});
**theme** *string*
**default:** null. Inherited from parent.
设置滑块的主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。默认情况下,这将继承与其父容器相同的样本颜色。该选项也作为数据属性公开:data-theme=”a”.
$( “#element1” ).slider({ theme: "a" });
**trackTheme** *string*
**default:** null. Inherited from parent.
为滑块滑动的轨道设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。默认情况下,如果没有显式设置,它将继承与其父容器相同的样本颜色。该选项也作为数据属性公开:data-track-theme=”a”.
$( “#element1” ).slider({ trackTheme: "a" });
滑块方法
slider
插件有以下几种方法:
enable:
启用禁用的滑块或开关控制。
$(“#element1” ).slider( “enable” );
disable:
禁用滑块或开关控制。
$( “#element1” ).slider( “disable” );
refresh:
更新自定义滑块或开关控件。
这将更新自定义滑块或开关,以反映本机元素的值。例如,我们可以动态更新我们的开关或滑块,并调用“refresh
”来重建控件。
// Set the switch to “on” and refresh it var switch **=** $**(** "#switch1" **);** switch**[**0**].**selectedIndex **=** 1**;**
switch**.**slider**(** "refresh" **);**
// Maximize the slider's volume control and refresh it $**(** "#volume" **).**val**(** 10 **).**slider**(** "refresh" **);**
滑块事件
slider
插件支持以下事件:
create:
当滑块或开关控件被创建时触发
创建自定义滑块或开关控件时会触发此事件。它不用于创建自定义元素。
$( '<select name="switch2" id="switch2">...</select>' ) .insertAfter( “#element1” ) .slider({ create: function(event) { console.log( "Creating new element..." ); });
开关控制
开关控制(见图 4–18)通常用于管理布尔开/关标志。
图 4–18。 开关控制
例如,开关控件通常是允许用户操作应用设置的首选方式,因为它们简单易用。要翻转开关,用户可以轻触控件或滑动开关。要创建一个开关控件,添加一个带有data-role=”slider”
和两个选项的选择元素来管理开/关状态(参见清单 4–25)。
清单 4–25。 开关控制(ch4/switch-control.html)
<label for="alerts">Alerts:</label> <select name="slider" id="alerts" **data-role="slider"**> **<option value="off">Off</option>** **<option value="on">On</option>** </select>
开关控件也由两个主题化组件组成。有被称为滑块的前景组件和被称为轨道的背景组件。这些组件中的每一个都可以单独设置主题。要主题化滑块,将data-theme=”a”
属性添加到select
元素中。此外,为了给音轨添加主题,将data-track-theme=”a”
属性添加到select
元素中:
<select name="slider" **data-theme="b" data-track-theme="c"** data-role="slider">
<option value="off">Off</option> <option value="on">On</option> </select>
动态开关控制
如前所述,slider
插件是自动增强开关控制的小部件。有了这个插件,我们可以动态地创建、启用、禁用和打开开关(参见清单 4–26)。slider
插件的完整列表在之前的“动态滑块”一节中有记载。相同的 API 可重复用于滑块和开关。
清单 4–26。 动态开关控件(CH4/Dynamic-switch-control . html)
`// Create switch with markup-driven options
$( '' )
.insertAfter( “#foo” )
.slider();
// Create switch with plugin-driven options
$( '' )
.insertAfter( “#switch1” )
.slider({
theme: "b",
trackTheme: "c",
disabled: false
});`
原生形态元素
jQuery Mobile 自动增强页面中定义的所有表单元素。然而,如果你想回到本地控制(见图 4–18)这可以在全局或现场级配置(见清单 4–27)。
图 4–19。 原生形态元素
清单 4-27。 原生表单元素(ch4/native.html)
`// Selectively choose which elements are native with data-role=”none”
<input type="text" name="name" id="name" value="" data-role="none" />
<select name="slider2" id="slider2" data-role="none">
// Globally configure native elements by selector
\((document).bind('mobileinit',function(){
**\).mobile.page.prototype.options.keepNative = "input, select";**
});`
要单独设置一个表单字段以显示其本地控件,请将data-role=”none”
属性添加到其元素中。或者,当mobileinit
事件初始化时,您可以通过设置keepNative
选择器来全局配置哪些表单元素应该本地呈现。例如,在清单 4–27 中,我们配置了我们的选择器来自动显示所有的input
和select
元素的原始外观。我们将在第八章“配置 jQuery Mobile”中更深入地讨论如何配置 jQuery Mobile。
HTML5 提供了几个新的输入类型来帮助收集日期和时间输入。我们现在有了时间、日期、月、周、日期时间和日期时间本地输入类型(参见清单 4–28)。
清单 4–28。 HTML5 日期(ch4/dates.html)
<input **type="time"** name="time" /> <input **type="datetime-local"** name="dtl" /> <input **type="date"** name="date" /> <input **type="month"** name="month" /> <input **type="week"** name="week" /> <input **type="datetime"** name="dt" />
对这些新的 HTML5 输入类型的支持依赖于浏览器(见[
www.quirksmode.org/html5/inputs.html](http://www.quirksmode.org/html5/inputs.html)
)。支持这些功能的新浏览器将显示有用的日期选择器(见图 4–20),不支持的浏览器将退回到文本输入。
图 4–20。 HTML5 日期
Mobiscroll Date Picker
Mobiscroll 6 是一款针对触摸屏设备优化的日期选择器。Mobiscroll API 是可配置的, 7 允许显示多个日期和时间组合(参见图 4–21)。此外,Mobiscroll 是可主题化的,也可以定制以显示任何必要的数据(参见图 4–22)。
图 4–21。 移动滚动日期选择器
图 4–22。 用自定义列表移动鼠标
例如,我们可以更新 MobiScroll 选项来创建一个定制的电影搜索(参见清单 4–29)。Mobiscroll 插件是一个灵活的控件,可以用于许多不同的用例。
6 见[
code.google.com/p/mobiscroll/](http://code.google.com/p/mobiscroll/)
。
7 见 http://code.google.com/p/mobiscroll/wiki/Documentation
。
清单 4-29。【mobis roll(CH4/mobis roll . html)
`// Import the Mobiscroll resources
// Display the default date picker (see Figure 4–21).
$( “#element1” ).scroller();
// Display a custom filter for a movie search (see Figure 4–22).
$( "#element2" ).scroller({
setText: 'Search',
theme: 'sense-ui',
wheels: [{
'Rating': { '5-star': '*****', '4–star': '****' ... },
'Genre': { 'action': 'Action', 'comedy': 'Comedy', ...},
'Screen': { '3d': '3D', 'imax': 'IMAX', 'wide': 'Wide' }
}]
});`
总结
在本章中,我们回顾了每个标准 HTML 表单组件,并了解了 jQuery Mobile 如何自动增强每个组件,以便在所有设备上提供统一的用户体验。
当我们回顾每个组件时,我们讨论了它的用法,并确定了它能很好解决的常见用例。我们还回顾了每个表单元素特有的 jQuery Mobile 数据属性,并查看了如何修改这些属性来配置和样式化表单的代码示例。此外,我们回顾了与每个表单组件相关联的插件,并了解了当用户需要更动态的体验时,我们如何利用插件 API 来动态地创建、增强和更新我们自己的组件。
最后,我们探索了 Mobiscroll 插件的特性,并了解了它如何为日期选择器、搜索过滤器或自定义列表提供优雅而灵活的界面。
在第五章中,我们的重点将从收集用户信息转移到呈现用户信息。特别是,我们将看到我们可以样式化和配置信息列表的许多方法。
五、列表视图
列表是一种流行的用户界面组件,因为它们使浏览体验变得非常简单和高效。列表也是一个非常灵活的组件,可以以多种方式进行样式化,并且可以很好地适应不同的屏幕尺寸。无论我们是在浏览邮件、联系人、音乐还是设置,这些应用都以略微不同的风格显示信息列表。从只包含文本的基本列表到包含图形和详细元数据的复杂列表,列表必须足够灵活以支持多种配置。幸运的是,jQuery Mobile 支持所有这些列表配置,甚至更多。在本章中,我们将探索在 jQuery Mobile 中设计和配置列表的细节。我们还将了解如何在列表中添加搜索过滤器。最后,我们将回顾列表视图插件 API,看看我们如何动态创建和更新列表的例子。
列出基础知识
当我们将data-role=”list”
属性添加到列表元素中时,jQuery Mobile 会自动将任何本地 HTML 列表(<ul>
或<ol>
)增强到移动优化视图中。默认情况下,增强列表将显示边对边,如果我们的列表项包含链接,它们将显示为带有右对齐箭头图标的触摸友好按钮(参见图 5–1 和在清单 5–1 中产生它的代码片段)。默认情况下,列表将使用“c”色样(灰色)来设置样式。要应用替换主题,请将data-theme
属性添加到列表元素或列表项中(<li>
)。
图 5–1。 基本列表
清单 5–1。 基本列表(ch5/list-basic.html)
`<ul data-role="listview" data-theme="c">
插图列表
插入列表不会边对边显示。相反,插入列表会自动包裹在圆角块中,并设置边距以增加间距。要创建一个插入列表,将data-inset="true"
属性添加到列表元素中(参见图 5–2 和 5–3,以及清单 5–2 中的相关代码)。
图 5–2。 插入列表(iOS)
图 5–3。 插入列表(Windows Phone 7)
清单 5–2。 插入列表(ch5/list-inset.html)
`
- Contact Options
- Call
- ...
列出分隔符
列表分隔线可以用作一组列表项的标题。例如,如果我们的应用有日历列表,我们可以选择按天对日历事件进行分组(参见 Figure 5–4)。列表分隔线也可以用作插入列表的标题。在前面的例子中,我们也用列表分隔线设置了插入列表的标题(参见图 5–2 和清单 5–2)。
要创建列表分隔线,请向任何列表项添加data-role="list-divider"
属性。列表分隔线的默认文本将左对齐。
提示:在图 5–4 中,列表项同时包含左对齐和右对齐的文本。要右对齐文本,用包含 ui-li-aside 类的元素将它包装起来(参见清单 5–3)。
默认情况下,列表分隔线将使用"b"
样本(浅蓝色)的颜色。要应用另一个主题,请向 list 元素添加data-divider-theme="a"
属性。
图 5–4。 列表分隔符
清单 5–3。 列表分隔符(ch5/list-dividers.html)
`
6 PM Birthday Party
<li data-role="list-divider" data-divider-theme="a">
Mon <p class="ui-li-aside">Feb 6 2012
带有缩略图和图标的列表
我们可以在列表项的左侧添加缩略图,方法是在列表项中添加一个图像作为第一个子元素(参见图 5–5 和清单 5–4 中的相关代码)。该框架将图像缩放到 80 像素见方。
图 5–5。 带缩略图的列表
清单 5–4。 带缩略图列表(ch5/list-thumbnails.html)
`
`我们也可以使用更小的图标来代替缩略图。要在列表项中使用标准的 16x16 像素图标,请将类别ui-li-icon
添加到图像元素中(参见图 5–6 和清单 5–5 中的相关代码)。
图 5–6。 带图标的列表
清单 5–5。 带图标列表(ch5/list-icons.html)
`
- User Reviews
<img src="img/111-user.png" class="ui-li-icon">
Go See It!
This movie had a strong script and ...
...
拆分按钮列表
在您需要支持每个列表项的多个操作的情况下,我们可以创建一个拆分按钮列表,其中有一个主要和次要按钮可供选择。例如,我们可以修改原来的电影列表示例来支持多个动作。我们的主按钮将继续显示电影细节,我们新的辅助按钮可用于购买门票(参见图 5–7)。
图 5–7。 带拆分按钮的列表
要创建一个拆分按钮,在列表项中添加一个二级链接,框架会添加一条垂直线来划分主要和二级动作(见清单 5–6)。
清单 5–6。 带拆分按钮的列表(ch5/List-split-buttons . html)
`<ul data-role="listview" data-split-icon="star" data-split-theme="d">
Kung Fu Panda
Rated: PG
Runtime: 95 min.
Buy Tickets
... `
要设置所有次级按钮的图标,请将data-split-icon
属性添加到列表元素,并将其值设置为标准图标(参见 Table 4–1)或自定义图标。默认情况下,辅助按钮将使用“b”样本(浅蓝色)的颜色。要应用替代主题,请向 list 元素添加 data-split-theme 属性。
编号列表
使用有序列表<ol>
时将创建编号列表(参见图 5–8 和清单 5–7 中的相关代码)。
图 5–8。 列表与数字
清单 5–7。 带编号的列表(ch5/list-numbered.html)
`
- The Amazing Spider-Man
- The Dark Knight Rises
...
默认情况下,框架会在每个列表项的左边添加数字索引。当显示可以按顺序排列的项目列表时,这些列表非常有用。例如,我们的“收视率最高的”电影视图是一个编号列表的理想候选,因为该序列可以快速关联哪些电影是收视率最高的。
只读列表
列表视图也可以显示数据的只读视图。用户界面看起来非常类似于我们之前展示的交互视图,除了右箭头图标-唯一的图像已经被移除,字体大小和填充稍微变小。要创建一个只读列表,只需删除我们在前面的例子中使用的锚标签(参见图 5–9 和清单 5–8 中的相关代码)。
图 5–9。 带有只读项目的列表
清单 5–8。 带只读项的列表(ch5/list-readonly.html)
`
Kung Fu Panda
Rated: PG
Runtime: 95 min.
...
列出徽章(数气泡)
列表标记或计数气泡是突出显示的椭圆形,通常表示可供查看的新项目的数量。例如,徽章通常用在邮件应用中,用来指示您有多少未读邮件。在我们的示例中,徽章用于指示何时添加了关于电影评论的评论(参见 Figure 5–10)。徽章可以用来表达任何类型的元数据。
图 5–10。 用徽章或数数气泡列表
要创建一个徽章,用包含类ui-li-count
的元素包装徽章的文本。默认情况下,徽章将使用“c”色样(灰色)进行设计。要应用一个替换主题,将data-count-theme
属性添加到列表元素中(参见清单 5–9)。
清单 5–9。 带徽章或计数气泡的列表(ch5/list-badges.html)
<ul data-role="listview" data-inset="true" **data-count-theme="e"**> <li data-role="list-divider">Comments</p></li> <li> <img src="img/111-user.png" class="ui-li-icon">
`
Thanks for the review. I'll check it out this weekend.
<span class="ui-li-count">1 day ago
`
用搜索栏过滤列表
jQuery Mobile 有一个非常方便的过滤列表的客户端搜索特性。要创建搜索栏,将data-filter=”true”
属性添加到列表中。然后,框架将在列表上方追加一个搜索过滤器,默认的占位符文本将显示单词“Filter items ...”(参见图 5–11 和清单 5–10 中的相关代码)。
图 5–11。 列表过滤(未过滤)
清单 5–10。 列表过滤(ch5/list-filter.html)
`<ul data-role="listview" data-filter="true" data-filter- placeholder="Search...">
Mon
Feb 6 2012
6 PM Birthday Party
有两个选项可用于配置占位符文本:
- 您可以通过在列表元素上添加
data-filter-placeholder
属性来配置占位符文本(参见清单 5–10)。 - 或者,您可以通过绑定到
mobileinit
事件并将filterPlaceholder
选项设置为任意自定义占位符值:$(document).bind('mobileinit',function(){ $.mobile.listview.prototype.options.filterPlaceholder="Search.."; });
,将占位符文本全局设置为 jQuery Mobile 配置选项
我们将在第八章“配置 jQuery Mobile”中更详细地讨论配置 jQuery Mobile。
当您开始在搜索过滤器中输入文本时,客户端过滤器将只显示与通配符搜索匹配的项目(参见 Figure 5–12)。
图 5–12。 【列表过滤(已过滤)】
如果您需要更改默认搜索功能,有两个选项可以覆盖用于过滤的回调:
首先,您可以通过绑定到mobileinit
事件并将filterCallback
选项设置为任何自定义搜索功能,将搜索功能作为 jQuery Mobile 配置选项进行全局更新。例如,这里我们将回调设置为使用“开始于”搜索:
$(document).bind('mobileinit',function(){ $.mobile.listview.prototype.options.filterCallback = function( text, searchValue ){ // Use a "starts with" search return !(text.toLowerCase().indexOf( searchValue ) === 0); }; });
回调函数有两个参数,text
和searchValue
。text
参数包含列表项的文本,searchValue
参数包含搜索过滤器的值。通配符搜索的默认行为编码为:
return text.toLowerCase().indexOf( searchValue ) === -1;
如果回调返回列表项的真值,它将从搜索结果中隐藏。
或者,我们也可以在列表创建后动态配置我们的搜索功能。例如,在我们的页面加载之后,我们可以为特定的列表应用新的搜索行为:
$("#calendar-list").listview('option', 'filterCallback', function( text, searchValue ) { // Use a "starts with" search return !(text.toLowerCase().indexOf( searchValue ) === 0); } );
默认情况下,搜索框将从其父容器继承其主题。要配置一个替代主题,请将data-filter-theme
属性添加到列表元素中。
动态列表
listview
插件是自动增强列表的小部件。我们可以利用这个插件来动态地创建和更新我们的列表。有两个选项可用于创建动态列表。您可以使用标记驱动的方法动态创建列表,或者通过在listview
插件上显式设置options
(参见清单 5–11)。
清单 5–11。 listview 插件示例(ch5/dynmic-lists.html)
`// Create list with markup-driven options
$( '
- Genres
- Action
- Comedy
.insertAfter( "#list0" )
.listview();
// Create list with plugin-driven options
$( '
- Genres
- Action
- Comedy
.insertAfter( "#list1" )
.listview({
theme: "d",
dividerTheme: "a",
inset: true,
});
// Add a new item to an existing list
$( "#list1" )
.append('
.listview(“refresh”);`
列表选项
listview
插件有以下选项:
**countTheme** *string*
默认:“c”
为徽章或计数气泡设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-count-theme=”a”.
$( “#list1” ).listview({ countTheme: "a" });
**dividerTheme** *string*
**default:** "b"
为列表分隔线设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-divider-theme=”a”.
$( “#list1” ).listview({ dividerTheme: "a" });
**initSelector** CSS selector string
**default:** ":jqmData(role='listview')"
initSelector 用于定义选择器(元素类型、数据角色等。)用于触发小部件插件的自动初始化。例如,默认选择器匹配的所有元素都将被listview
插件增强。要覆盖这个选择器,绑定到mobileinit
事件并根据需要更新选择器:
$( document ).bind( "mobileinit", function(){
$.mobile.listview.prototype.options.initSelector = "...";
});
**inset** *boolean*
**default:** false
当此选项设置为 true 时,将创建一个插入列表。默认情况下,将创建一个基本列表。该选项也作为数据属性公开:data-inset=”true”.
$( “#list1” ).listview({ inset: true });
**splitIcon** *string*
**default:** "arrow-r"
建立拆分按钮列表时设置次级按钮的图标。该选项也作为数据属性公开:data-split-icon=”star”.
$( “#list1” ).listview({ splitIcon: "star" });
**splitTheme** *string*
**default:** "b"
创建拆分按钮列表时,设置辅助按钮的主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-split-theme=”a”.
$( “#list1” ).listview({ splitTheme: "a" });
**theme** *string*
**default:** "c"
设置列表的主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-theme=”a”.
$( “#list1” ).listview({ theme: "a" });
列举方法
listview
插件有以下方法:
refresh
: 更新自定义列表。
这将更新自定义列表以反映本地列表元素的值。例如,如果我们向现有列表中添加一个新项目,我们必须调用“refresh
”来重建列表项目:
` // Add an item to an existing list and refresh the list item
$( "#list1" )
.append('
**.listview(“refresh”); **
// Add list items to a new list and refresh the entire list
var markup = '
$( "#list2" )
.append(markup)
** .listview( "refresh", true );**`
列出事件
listview
插件支持以下事件:
create:
创建列表时触发
创建自定义列表时会触发此事件。它不用于创建自定义列表。
$( '<ul><li data-role="list-divider">Genres</li> <li><a href="#">Comedy</a></li></ul>' ) .insertAfter( "#list1" ) .listview({ inset: true, create: function(event) { console.log( "Creating list..." ); } });
总结
在本章中,我们回顾了非常流行的列表视图组件。列表视图是常用的,因为它们使浏览体验非常简单和高效。jQuery Mobile 列表可以用许多独特的方式进行样式化和配置。从基本列表到带有图像、分割按钮、分隔线或徽章的列表,我们有许多配置选项可供选择。
我们还看到了向列表中添加搜索过滤器是多么容易,并看到了如何在必要时覆盖默认搜索的例子。
最后,我们回顾了listview
插件 API,并看到了如何动态创建和更新列表的例子,以便为我们的用户提供更具交互性的体验。
在下一章中,我们将探索另一个流行的用户界面组件,jQuery Mobile 灵活的网格布局。我们将看到如何使用网格来创建响应式设计,我们也将看看如何用 CSS 渐变来增强我们的用户界面。
六、使用网格和 CSS 渐变格式化内容
移动应用通常将网格用于需要灵活的内容,并将其分组。对于需要这种行为的设计,jQuery Mobile 的响应式网格是一个有用的解决方案。在本章中,我们将回顾 jQuery Mobile grid 组件的基础知识,并展示几个如何在网格中设计图标、图形和文本样式的例子。我们还将创建可折叠的内容块,并讨论它们与内联页面结构相比的优势。最后,我们将使用 CSS 渐变对我们的设计进行一些修饰,并讨论 CSS 渐变在性能和渐进增强方面的优势。
网格布局
jQuery Mobile 的网格可配置为支持两到五列的布局。从 HTML 的角度来看,网格是用 CSS 属性配置的div
元素。网格是灵活的,会占用显示器的整个宽度。网格不包含边框、填充或边距,因此它们不会干扰其中包含的元素的样式。在我们看一个例子之前,让我们回顾一下标准的网格模板。
网格模板
当创建多列网格时,网格模板可能是一个有用的参考(参见清单 6–1)。
清单 6–1。 网格模板
`
**
`
创建网格时,您需要创建具有两个或更多内部块的外部网格容器:
-
Grid container: The grid container requires the CSS attribute
ui-grid-*
to configure the number of columns in the grid (see Table 6–1). For instance, to create a two-column grid we would set our grid CSS attribute toui-grid-a
. -
Blocks: The blocks are contained within the grid. The blocks require the CSS attribute
ui-block-*
to identify its column position (see Table 6–2). For instance, if we had a two-column grid, our first block would be styled with CSS attributeui-block-a
and the second block would be styled with CSS attributeui-block-b
.
两列网格
两列(50%,50%)网格显示在图 6–1 中,其相关代码显示在清单 6–2 中。
图 6–1。 两列网格
清单 6–2。 【两列网格】ch6/grid-2col.html
`
<div class="ui-grid-a">
<div class="ui-block-a">Block A
<div class="ui-block-b">Block B
`
外部网格配置了 CSS 网格属性ui-grid-a
。接下来,我们添加两个内部块。第一块被分配了一个 CSS 值ui-block-a
,第二列被分配了一个 CSS 值ui-block-b
。如图 Figure 6–1 所示,各列等距,无边界,每个块中的文本将在必要时换行。作为一个额外的好处,jQuery Mobile 中的网格是灵活的,可以在不同的显示尺寸上进行相应的渲染(参见图 6–2)。
图 6–2。 两列网格(风景)
带有 CSS 增强功能的三列网格
三列(33%,33%,33%)网格显示在图 6–3 中,其相关代码显示在清单 6–3 中。
图 6–3。 带有 CSS 增强功能的三列网格
清单 6–3。 【三列网格】ch6/grid-3col.html
`
<div class="ui-grid-b">
<div class="ui-block-a">
<div class="ui-bar ui-bar-e" style="height:100px">Block A
<div class="ui-block-b">
<div class="ui-bar ui-bar-e" style="height:100px">Block B
<div class="ui-block-c">
<div class="ui-bar ui-bar-e" style="height:100px">Block C
`
除了网格的 CSS 属性被配置为支持三列(ui-grid-b
)以及我们为第三列(ui-block-c
)添加了一个额外的块之外,它与我们之前看到的两列示例非常相似。我们还用可主题化的类来设计块的样式,这些类可以添加到任何元素中,包括网格。在这个例子中,我们添加了ui-bar
来应用 css 填充,添加了ui-bar-e
来应用“e
工具栏主题样本的背景渐变和字体样式。您可以使用a
到e
范围内的任何工具栏主题(ui-bar-*
)来设计您的模块。最后,为了创建一致的块高度,我们还设计了内嵌高度(style="height:100px"
)。从视觉上看,这些改进用线性背景渐变设计了我们的网格,我们的块现在用边界分隔开了。
带应用图标的四列网格
四列(25%、25%、25%、25%)网格显示在图 6–4 中,其相关代码显示在清单 6–4 中。
清单 6–4。 【四柱格】ch6/grid-4col.html
`
<div class="ui-grid-c" style="text-align: center;">
<div class="ui-block-a"><img src="img/cloud-default.png">
<div class="ui-block-b">
<div class="ui-block-c">
<div class="ui-block-d">
`
除了网格的 CSS 属性被配置为支持四列(ui-grid-c
,并且我们为第四列(ui-block-d
添加了一个额外的块之外,它与三列示例类似。此外,为了平衡和一致性,我们将应用图标置于网格中央(style="text-align:center;
)。视觉上,网格有均匀分布的应用图标,很像一个应用跳板。
图 6–4。 带应用图标的四列网格
带有表情图标的五列网格
五列(20%,20%,20%,20%,20%)网格显示在图 6–5 中,其相关代码显示在清单 6–5 中。
清单 6–5。 【五列网格】ch6/grid-5col.html
`
<div class="ui-grid-d" style="text-align: center;">
这个例子非常类似于我们之前看到的四列网格,除了网格的 CSS 属性被配置为支持五列(ui-grid-d
)并且我们已经用为第五列(ui-block-e
)添加了一个额外的块。每个区块包含一个独特的表情图标。 1
图 6–5。 五列网格
注意:表情图标是图像的一个很好的替代品,因为它们消耗零 HTTP 请求,并且它们的有效载荷只是几个字符的文本。不幸的是,表情符号图标目前仅在 iOS 中受支持。
1 见[
pukupi.com/post/1964](http://pukupi.com/post/1964).
多行网格
到目前为止,我们只看到了单行网格。要添加额外的行,只需为每个连续的行重复第一行的块模式(参见清单 6–6 中的图 6–6 及其相关代码)。生成的网格包含五列和三行。列的间距相等,可以在块组件上手动调整行高。
图 6–6。 多行网格
清单 6–6。 【多行网格】ch6/grid-multi-row.html
`
`
不均匀网格
到目前为止,所示的每个网格示例都有均匀间隔的列,因为默认情况下 jQuery Mobile 会均匀间隔所有的列。但是,如果您需要定制列宽,我们可以在 CSS 中调整宽度。例如,我们可以通过设置每个块的自定义宽度,将两列网格的默认宽度修改为 25/75%(参见图 6–7 及其在清单 6–7 中的相关代码)。因此,我们的网格可以修改,以支持广泛的替代维度。
图 6–7。 不均匀网格
清单 6–7。 【网格不均匀】ch6/grid-uneven.html
``
跳板
跳板是应用网格布局的理想选择。在下面的例子中,我们将看到两种类型的跳板。首先,我们会看到一个带有应用图标的跳板(见图 6–8),其次我们会看到一个带有雕刻图标的跳板(见图 6–9)。
图 6–8。 带 app 图标的跳板
图 6–9。 带有浮雕图标的跳板
你准备好接受跳板挑战了吗?如果你是,我鼓励你创造一个和这两个人物非常相似的跳板。从网格的角度来看,这两个例子的配置是相同的。然而,带有 Glyphish 图标的跳板(见清单 6–9)的风格与带有应用图标的跳板(见清单 6–8)略有不同,以调整其不均匀的图标高度。
清单 6–8。 带 app 图标的跳板(ch6/springboard1.html
)
`
`清单 6–9。 带有雕刻图标的跳板(ch6/springboard2.html
)
`
`可折叠的内容块
你有没有发现自己反复滚动来浏览整个手机页面的内容?虽然这对于你的手指来说可能是一个很好的锻炼,但当用户必须重复滚动时,这可能是一个麻烦的用户体验。如果您正在寻找一个更有用的替代方案,您可能需要考虑将您的内容分组到可折叠的内容块中。
提示:与内嵌页面结构相比,可折叠内容块有几个优点。首先,我们可以将内容折叠成分段的组,使它们在单个视图中可见(参见图 6–10)。其次,我们的用户会更有效率,因为我们已经从用户体验中消除了滚动。
图 6–10。 内容块(所有块折叠)
创建可折叠内容块所需的标记如清单 6–10 所示。
清单 6–10。ch6/collapsible-block.html
可折叠内容块
`
<div data-role="collapsible" data-collapsed="true" data-theme="a" data-content-theme="b">
Wireless
- Notifications
- Location Services
<div data-role="collapsible"> data-theme="a" data-content-theme="b">
Applications
- Faceoff
- LinkedOut
- Netflicks
`
创建可折叠块需要两个元素:
-
Create a container and add the
data-role="collapsible"
attribute. Optionally, you may configure the container to be collapsed or expanded by adding thedata-collapsed
attribute. By default, a collapsible section will be shown expanded (data-collapsed="false"
). To initially show the section as a collapsed block, adddata-collapsed="true"
to the container. For instance, if we launch the code in Listing 6–10, the initial view will appear as Figure 6–11. In the code listing, we have explicitly collapsed all content blocks except for the “Applications” section which will expand by default.图 6–11。 内容块(一个块展开)
-
在容器中,添加任何 header 元素
(H1-H6).
框架会将 header 设计成看起来像一个可点击的按钮,带有一个左对齐的加号或减号图标,表示它是可扩展的。
在标题之后,您可以向可折叠块添加任何 HTML 标记。框架将把这个标记包装在容器中,当点击标题时,容器将展开或折叠。你可以通过在可折叠容器中添加data-theme
和data-content-theme
属性来分别设置可折叠块及其相关按钮的主题(参见清单 6–10)。
注意:一个可折叠块允许你一次展开或折叠多个块(见图 6–12)。在下一节中,我们将看到在处理可折叠集合时这是不允许的。
图 6–12。 内容块(所有块展开)
可折叠套
可折叠组件(参见图 6–13)与可折叠积木相似,只是它们的可折叠部分在视觉上组合在一起,并且一次只能展开一个部分,这使得可折叠组件看起来像手风琴(参见图 6–14)。
图 6–13。 内容设置(折叠)
图 6–14。 内容设置(扩展)
当打开集合中的新节时,以前打开的任何节都将自动折叠。
可折叠集合的标记与我们之前在构建可折叠块时看到的标记相同。然而,为了创建手风琴式的行为和分组,我们需要添加一个带有data-role="collapsible-set"
的父包装器,如清单 6–11 所示。
清单 6–11。 可折叠设置(ch6/collapsible-set.html)
`
<div data-role="collapsible-set"> data-theme="a" data-content-theme="b">
Wireless
- Notifications
- Location Services
Applications
- Faceoff
- LinkedOut
- Netflicks
...
使用 CSS 渐变的样式
想给你的移动用户界面添加一点润色吗?尝试在通常使用背景图像的地方使用 CSS 渐变。CSS 渐变为图像提供了一个高性能的替代品,它们在灵活的布局中工作得非常好,并且在不受支持的浏览器中优雅地退化。例如,我们可以将一个原始的跳板(见图 6–15)改造成一个更加优雅的展示(见图 6–16 和图 6–17)并添加渐变。
图 6–15。 没有 CSS 渐变的跳板
图 6–16。 带有 CSS 渐变的跳板(iOS)
图 6–17。 带有 CSS 渐变的跳板(安卓)
任何使用背景图像的地方都可以使用渐变。例如,它们最常用于设计标题、内容和按钮的背景。此外,有两种类型的 CSS 渐变:线性和径向。线性渐变是两者中比较简单的,如果你不太熟悉它们的语法,CSS 渐变生成器 2 可以帮助你开始。产生背景线性渐变的 CSS 如清单 6–12 所示。
清单 6–12。 背景渐变
**.background-gradient** { background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.22, rgb(92,92,92)), color-stop(0.57, rgb(158,153,158)),
` color-stop(0.84, rgb(92,92,92))
);
}
2 见[
www.westciv.com/tools/gradients/](http://www.westciv.com/tools/gradients/)
或[
gradients.glrzad.com/](http://gradients.glrzad.com/).
虽然这个 CSS 渐变是针对最流行的 WebKit 布局引擎(参见图 6–18)的,但是您可以通过包含特定于供应商的前缀来添加对其他浏览器的支持。
图 6–18。 Webkit 用法
例如,为了在 Mozilla 浏览器上渲染我们的渐变,我们将添加带有-moz-
厂商前缀的版本(参见清单 6–13)。
清单 6–13。 支持 Mozilla 的背景渐变
.background-gradient { background-image: **-webkit-gradient**( linear, left bottom, left top, color-stop(0.22, rgb(92,92,92)), color-stop(0.57, rgb(158,153,158)), color-stop(0.84, rgb(92,92,92)) ); background-image: **-moz-linear-gradient**( 90deg, rgb(92,92,92), rgb(158,153,158), rgb(92,92,92)); }
页眉的渐变实际上是三个独立渐变的叠加。包括一个线性梯度和两个径向梯度。径向渐变创建圆形渐变效果。创建标题渐变的代码如清单 6–14 所示。
清单 6–14。 跳板坡度
`.header-gradient {
background-image:
-webkit-gradient(
linear, left top, left bottom,
from( rgba( 068,213,254,0 )),
color-stop(.43, rgba( 068,213,254,0 )),
to( rgba( 068,213,254,1 ))),
-webkit-gradient( radial,
50% 700, 690,
50% 700, 689,
from( rgba( 049,123,220,0 )),
to( rgba( 049,123,220,1 ))),
-webkit-gradient(
radial,
20 -43, 60,
20 -43, 40,
from( rgba( 125,170,231,1 )),
to( rgba( 230,238,250,1 )));
}
总结
在这一章中,我们回顾了 jQuery Mobile 基于网格的设计的有用性,并看到了我们如何快速地在网格模板中设计内容(参见清单 6–1)。jQuery Mobile grid 是需要响应和分组的内容的理想解决方案。我们的网格可以包含任何内容,我们看到了几个使用文本、图标和图形的网格示例。
我们还回顾了可折叠的内容块,并讨论了它们与内联页面结构相比的优势。可折叠块可以是一种有效的可用性模式,因为它们有助于在单一视图中显示所有内容,并且有助于消除用户体验中的滚动。因此,用户对应用的体验将更加高效。
最后,我们看到了如何用 CSS 渐变来润色我们的设计。CSS 渐变是图像的一种高性能替代品,它们在灵活的布局中工作得非常好,在不受支持的浏览器中会逐渐退化。
在第七章中,我们将继续我们的布局设计之路,仔细看看 jQuery Mobile 的主题框架。
七、创造主题化的设计
jQuery Mobile 有一个内置的主题框架,允许设计人员快速定制或重新设计他们的用户界面。主题框架利用了 CSS3 的许多特性,这有助于构建更优雅、更具响应性的设计。例如,通过利用 CSS3,主题框架能够应用圆角、阴影和渐变,而不必依赖于图像。这是一个性能优势,因为该框架可以提供更有吸引力的接口,而没有额外的 HTTP 请求开销。本质上,我们有一个轻量级的主题框架,可以在所有浏览器上呈现统一的设计。
在这一章中,我们将讨论主题框架的基础,并回顾 jQuery Mobile 中包含的默认主题。我们还将探索将主题分配给组件的三种方式。虽然所有的组件都可以使用data-theme
属性显式地设置它们的主题,但是大多数组件也有默认的主题,并且也可以从父容器继承它们的主题。我们将讨论它们的优点,看看每一个的例子,并讨论主题应用于组件的优先级。
最后,我们将看看如何创建我们自己的自定义主题。如果您需要创建更丰富的设计,或者如果您需要创建与您的公司品牌紧密匹配的设计,那么创建自定义主题将是必要的。创建自定义主题有两个选项,我们将一步步地看每一个的例子。第一种选择是手动方法,它让设计者完全控制他们的布局;第二种是使用主题滚轮 1 ,这是一种基于网络的工具,可以自动完成创建新主题的过程。
1 见[
jquerymobile.com/themeroller](http://jquerymobile.com/themeroller)
主题基础知识
在很多例子中,我们已经看到了如何使用data-theme
属性将替换主题应用到页面容器(页面、页眉、内容、页脚)和表单元素中。例如,我们可以使用一个没有主题的页面(见图 7–1)并用一个不同的标题和列表主题(见图 7–2)重新设计它的样式,并简单地添加data-theme
属性(见清单 7–1)。
图 7–1。 带有默认主题的列表
图 7–2。 列表与备选主题
清单 7–1。 数据-主题属性(ch7/theme-list2.html)
`
<div data-role="header" data-theme="b">
jMovies
<ul data-role="listview" data-inset="true" data-theme="a">
主题和样本
jQuery Mobile CSS 文件总是我们在 head 元素中导入的第一个资产(参见清单 7–2)。该文件包含 jQuery Mobile 应用的默认结构和主题。花一点时间,用您最喜欢的编辑器探索这个文件的内容。
清单 7–2。 jQuery Mobile CSS 导入
`
** **
jQuery Mobile CSS 文档分为两个部分:主题部分和结构部分。
-
Theme – The top half of the document contains the default theme settings. The theme settings manage the visual styling (backgrounds, borders, color, font, shadows) for all components. When setting the
data-theme
attribute, we are able to choose from five different options (a, b, c, d, e). These letters (a-e) are technically referred to as swatches. As you were reviewing the jQuery Mobile CSS file you may have noticed that the first swatch to appear within the CSS file was swatch “a” (see Listing 7–3).清单 7–3。 jQuery Mobile CSS 样本“a”(部分列表)
/* **A** ---------------------------------------------------------------------*/ .ui-bar-**a** { border: 1px solid #2A2A2A; background: #111111; color: #ffffff; font-weight: bold; text-shadow: 0 -1px 1px #000000; ... background-image: linear-gradient(top, #3c3c3c, #111); } .ui-body-**a** { border: 1px solid #2A2A2A; background: #222222; color: #fff; text-shadow: 0 1px 0 #000; font-weight: normal; background-image**:** linear-gradient(top, #666**,** #222**);** } ...
主题部分分为以下几个小节:
-
样本——默认情况下,jQuery Mobile 有五个样本可供选择(a、b、c、d、e ),您可以根据需要添加任意数量的独特样本。样本允许我们为组件配置独特的背景、边框、颜色、字体和阴影。为简单起见,新样本的命名约定是基于字母的(a-z)。但是,样本名称的长度没有限制。我们将在本章的后面看到创建我们自己的自定义色板的例子。
-
Global theme settings – Global theme settings are configured after the swatches. These settings add visual styling enhancements to buttons, such as rounded corners, icons, overlays, and shadows. Since these settings are global, they will be inherited by all swatch configurations (see Listing 7–4).
清单 7–4。【jQuery 手机全球主题造型(部分上市)
/* Active class used as the "on" state across all themes -----------------------------------------------------------------------*/ .ui-btn-active { border: 1px solid #155678; background: #4596ce; font-weight: bold; color: #fff; cursor: pointer; text-shadow: 0 -1px 1px #145072; text-decoration: none; ... }
-
Structure – The latter half of the jQuery Mobile CSS file contains structure styling that primarily includes positioning, padding, margin, height, and width settings (see Listing 7–5).
清单 7–5。 jQuery Mobile 结构造型(部分清单)
`/* some unsets - more probably needed */
.ui-mobile, .ui-mobile body { height: 100%; }
.ui-mobile fieldset, .ui-page { padding: 0; margin: 0; }
.ui-mobile a img, .ui-mobile fieldset { border: 0; }...
.ui-checkbox, .ui-radio {
position:relative; margin: .2em 0 .5em; z-index: 1;
}
.ui-checkbox .ui-btn, .ui-radio .ui-btn {
margin: 0; text-align: left; z-index: 2;
}`现在我们已经了解了 jQuery Mobile 的主 CSS 文件,让我们更仔细地看看 jQuery Mobile 包含的五个样本,看看它们是如何出现在几个不同的组件中的(参见 Figure 7–3–7–6)。
图 7–3。 格子色板
图 7–4。 列出色板
图 7–5。 纽扣布样
图 7–6。 表单字段样本
为了在所有组件中保持样例的样式一致,以下视觉优先级约定用于每个样例:
-
“a”(黑色)视觉优先级最高。
-
“b”(蓝色)是二级水平。
-
" c" -(灰色)基线。
-
“d”-(白/灰)一个交替的二级水平。
-
“e”-(黄色)强调色。
主题默认值
如果您没有向页面添加data-theme
属性,jQuery Mobile 将为所有页面容器和表单元素应用默认主题(参见 Table 7–1)。
例如,如果我们创建一个基本的 jQuery Mobile 页面,而没有显式地设置它的主题,那么我们的元素将回到它们的默认主题或者继承它们的父容器的主题。在 Figure 7–7 中,默认主题应用于页面、页眉、页脚、内容和列表元素,而表单元素继承了它们的主题。
图 7–7。 带有默认和继承主题的页面
通过参考我们的“组件默认主题”表(参见表 7–1,我们可以确定每个组件将应用什么默认主题。让我们仔细看看内容和按钮组件。默认情况下,内容组件将应用data-theme=”c”
。但是,按钮组件没有默认主题,因此它将从其父容器继承默认主题。在清单 7–6 中,按钮的父节点是内容容器;因此,按钮将继承主题“c”。此外,如果按钮在头部容器中,它将继承头部容器的主题。
清单 7–6。 带有默认主题的页面(ch7/theme-defaults.html)
`
default = "a"
default = "c"
- default = "b"
- default = "c"
- default = "c"
default = "a"
主题传承
组件也可以继承其父容器的主题。主题继承在两个方面是有益的。首先,它使设计者的设计过程更加有效,因为我们可以快速地在一个高层次(页面容器)设置一个主题,这个主题将级联到所有子组件,节省了宝贵的时间。其次,它使组件在整个应用中保持一致的风格。例如,在清单 7–7 中,我们用data-theme=”e”
设计了页面容器。因此,内容主题从其父容器继承了“e”主题(参见图 7–8)。
清单 7–7。 主题继承(ch7/theme-inheritance.html)
`<div data-role="page" data-theme="e">
No inheritance
Inherits "e"
- No inheritance
- No inheritance
- No inheritance
No inheritance
图 7–8。 主题传承
注意:不是所有的组件都会继承其父容器的主题。参考表 7–1 中的“继承父主题”一栏,了解不会继承父主题的组件列表。
我们还可以显式地设置单个组件的主题。这给了设计者在设计网站时的灵活性,可以帮助构建更丰富的设计(见图 7–9 和清单 7–8 中的相关代码)。
图 7–9。 显性主题
清单 7–8。 显性主题(ch7/theme-explicit.html)
`<div data-role="page" data-theme="e">
<div data-role="header" data-theme="b">
Theme = "b"
<div data-role="content" data-theme="d">
Theme = "d"
<ul data-role="listview" data-theme="e" data-divider-theme="e">
<li data-theme="b">Theme = "b"
<div data-role="footer" data-position="fixed" data-theme="b">
Theme = "b"
`
主题优先顺序
主题按以下优先顺序应用于组件:
-
显式主题——如果在任何组件上显式设置了
data-theme
属性,该主题将覆盖任何继承的或默认的主题。 -
继承的主题—继承的主题将覆盖所有默认主题。例如,在清单 7–7 中,内容容器从它的页面容器继承了主题“e ”,而页面容器覆盖了它的默认主题“c”。关于可能继承其主题的组件列表,请参考表 7–1 中的“继承父主题”栏。
-
Default themes—Default themes are applied when no themes are explicitly set or inherited. For a listing of default themes by component, refer to the “Default Theme” column in Table 7–1.
提示:默认情况下,内容容器的最小高度只会拉伸里面组件的高度。当内容的主题与其页面容器的主题不同时,这就是一个问题(参见图 7–10)。我们可以用 CSS 来解决这个问题。例如,我们可以将内容容器的最小高度设置为屏幕的高度(参见图 7–11):
ui-content { min-height:inherit; }
图 7–10。 内容高度不到 100%
图 7–11。 内容高度 100% (ch7/min-height.html)
自定义主题
jQuery Mobile 主题框架允许设计者快速定制或重新设计他们的用户界面。在本节中,我们将了解如何手动创建我们自己的自定义色板。如前所述,默认的 jQuery Mobile CSS 文档分为两个部分:主题部分和结构部分。在本练习中,我们将创建一个自定义样本,用于潜在危险动作的参考。例如,一个通用的用户体验指南鼓励开发者用红色突出显示控制潜在有害行为的按钮。在 jQuery Mobile 中,我们可以创建一个定制的样本来管理图标和/或按钮的视觉样式(背景、边框、颜色、字体、阴影),从而驱动我们的冒险行为。
要手动创建自定义样本,必须执行以下步骤:
-
First, create a separate CSS file for the custom theme (css/theme/custom-theme.css). This keeps the custom additions separate from the main jQuery Mobile CSS and will simplify future upgrades.
提示:如果您计划使用自定义主题来设计整个 jQuery Mobile 应用,建议使用 jQuery Mobile 下载网站上的纯结构 CSS 文件。对于不需要默认主题的应用来说,这是一个轻量级的选择,它简化了定制主题的管理(参见清单 7–9)。
清单 7–9。 jQuery Mobile 的无默认主题的结构文件
`
Custom Theme
** **
** **
` -
查找要作为基线参考的现有样本。在研究了现有的样本后,复制一个与你的新样本风格非常相似的样本。这将有助于最大限度地减少创建新样本所需的修改次数。对于我的新样本,我复制了“e”样本作为我的基线,因为“e”是一个重音样本,我们的潜在危险动作的新样本也可以划分到重音类别中。
-
Next, copy the baseline swatch and paste it into the custom-theme.css file. Then, rename the swatch so it is associated to a unique letter (f-z). For example, replace all CSS suffixes with “-e” to “-v” (see Listing 7–10). The new swatch can now be referenced with
data-theme=”v”
for any components that perform dangerous actions.清单 7–10。 仿照样本“e”定制“v”样本(ch7/CSS/theme/Custom-theme 9781430239666 . CSS)
/* **V** ----------------------------------------------------------------------*/ .ui-bar**-v** { font-weight**:** bold**;** border**:** 1px solid #999**;** background**:** #dedede**;** color**:** #000**;**
text-shadow**:** 0 1px 0px #fff**;** ** …** } .ui-btn-up**-v** { border: 1px solid #999; background: #e79696; color: #fff; text-shadow: 0 1px 0px #fff; ... }
-
Now the exciting task of updating the visual CSS settings (backgrounds, borders, color, font, and shadows) for our new swatch. For the new “v” swatch, I updated all buttons to have a red gradient background with white text (see Listing 7–11).
清单 7–11。 用红色背景渐变和白色文字更新“v”色板按钮(ch7/CSS/theme/custom-theme 9781430239666 . CSS)
/* V ----------------------------------------------------------------------*/ .ui-btn-up-v { border: 1px solid #999; background: **#e79696;** color: **#fff;** text-shadow: 0 1px 0px #fff; **background-image: -webkit-gradient(** ** linear, 0% 0%, 0% 100%, from(#E79696), to(#ce2021),** ** color-stop(.4,#E79696)** ** );** ** background-image: -webkit-linear-gradient(** ** 0% 56% 90deg,#CE2021, #E79696, #E79696 100%** ** );** ** background-image: -moz-linear-gradient(** ** 0% 56% 90deg,#CE2021, #E79696, #E79696 100%** ** );** ... }
-
接下来,我们需要将新的“v”样本与一个实际页面集成起来进行测试。我创建了两个页面来帮助测试新的“v”样本。在第一页,我想看看新的样本如何出现在一个只有图标的按钮上。在这个测试中,我创建了一个分割按钮列表,用二级按钮作为我们的删除图标,并用我们新的“v”样本设计二级按钮的样式(见图 7–12 和清单 7–12 中的相关代码)。
2 见[
jquerymobile.com/download](http://jquerymobile.com/download).
图 7–12。 红色图标背景为潜在危险动作
清单 7–12。 带“v”形样本的拆分按钮(ch7/custom1.html)
`
** **
** **
** ...**
-
Kung Fu Panda
Rated: PG
Runtime: 95 min.
Delete**
...`
-
In ThemeRoller, import an existing theme by clicking the “Import” link in the upper left corner (see Figure 7–18). For this exercise I am going to import and modify jQuery Mobile's default theme.
图 7–18。 导入已有的主题
-
导入主题后,确定要修改的样本。对于这一步,我将修改默认的“e”样本。
-
接下来,为我们的红色强调样本找到一个合适的基色。我们可以在快速观察栏或 Kuler 集成工具中找到合适的红色。
-
找到合适的基色后,我们现在可以用选择的颜色更新预览窗格中的元素。例如,我将用深红色强调色来设计标题和所有元素的样式。
-
在预览窗格中,进行任何必要的调整。例如,您可能想要稍微调整颜色或添加带有背景渐变的微妙效果。正如所料,ThemeRoller 使编辑和预览过程比手动方式更有效!
-
After you are comfortable with the layout of the new theme, you can download the CSS of the theme by clicking on the “Download Theme” link in the upper left corner of ThemeRoller (see Figure 7–19).
图 7–19。 下载主题
-
We can now begin referencing the new theme in our application (see Listing 7–14 and its related screenshot in Figure 7–20). Again, to help simplify the management of the custom themes it is recommended to load the structure file and your custom themes separately.
清单 7–14。 ThemeRoller 自定义主题导入(ch7/custom2.html)
`
Custom Theme
** **
** **
</head>Are you sure?<a href="#home" data-role="button" data-theme="e">Delete
Cancel
-
activeBtnClass(string, default: "ui-btnactive")
这个 CSS 类用来标识“活动”按钮并设置其样式。这个 CSS 属性通常用于设计和识别标签栏中的活动按钮。
-
activePageClass(string, default: “ui-page-active”)
分配给当前可见且活动的页面或对话框的 CSS 类。例如,当 DOM 中加载了多个页面时,活动页面将应用这个 CSS 属性。
-
ajaxEnabled(boolean, default: true)
尽可能通过 Ajax 动态加载页面。默认情况下,除了外部 URL 或标记有
rel="external"
或target="_blank"
属性的链接之外,所有页面都启用 Ajax 加载。如果 Ajax 被禁用,页面链接将加载常规的 HTTP 请求,而没有 CSS 转换。 -
allowCrossDomainPages(boolean, default: false)
使用 PhoneGap 开发时,建议将此配置选项设置为 true。这允许 jQuery Mobile 在 PhoneGap 中管理跨域请求的页面加载逻辑。
-
autoInitializePage(boolean, default: true)
对于希望完全控制页面初始化顺序的高级开发人员,您可以将此配置选项设置为
false
,这将禁用所有页面组件的自动初始化。这允许开发人员根据需要手动增强每个控件。 -
defaultDialogTransition(string, default: "pop")
转换到对话框时使用的默认转换。您可以将过渡设置为“
none
”,不进行过渡。 -
defaultPageTransition(string, default: “slide”)
转换到页面时使用的默认转换。您可以将过渡设置为“
none
”,不进行过渡。 -
gradeA(function that returns a boolean, default: browser must support media queries or support IE 7+);
jQuery Mobile 将调用这个方法来确定框架是否会应用动态 CSS 页面增强。默认情况下,该方法将对所有支持媒体查询的浏览器应用增强功能;然而,jQuery Mobile 只会增强 A 级浏览器的页面。IE 7 及以上版本被列为 A 级浏览器,它们的显示也将得到增强,例如,这是
$.mobile.gradeA
的当前功能:$.mobile.gradeA: function(){ return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7; }
-
hashListeningEnabled(boolean, default: true)
基于
location.hash
自动加载并显示页面。jQuery Mobile 监听location.hash
的变化以加载 DOM 中的内部页面。您可以禁用此选项并手动处理哈希更改,或者禁用此选项以深度链接的形式访问锚的书签。 -
loadingMessage(string, default: “loading”)
设置在基于 Ajax 的请求期间出现的加载消息。此外,您可以指定一个
false
(布尔值)来禁用该消息。此外,如果您想在运行时逐页更新加载消息,您可以在页面内更新它。例如:
`// Update loading message
$.mobile.loadingMessage = "My custom message!";// Show loading message
$.mobile.showPageLoadingMsg();` -
minScrollBack(string, default: 250)
设置返回页面时记忆的最小滚动距离。当返回页面时,当链接的滚动位置超出
minScrollBack
设置时,框架将自动滚动到启动过渡的位置或链接。默认情况下,滚动阈值为 250 像素。如果您想取消最小设置,使框架总是滚动,而不管滚动位置如何,请将该值设置为"0"
。如果您想禁用该功能,请将该值设置为"infinity"
。 -
nonHistorySelectors(string, default: “dialog”)
您可以指定从浏览器的历史堆栈中排除哪些页面组件。默认情况下,任何带有
data-rel="dialog"
的链接或者任何带有data-role="dialog"
的页面都不会出现在历史中。此外,这些非历史选择器组件在导航到它们的页面时不会更新它们的 URL,因此它们将不能被加书签。 -
ns(string, default: "")
jQuery Mobile 中自定义 data-*属性的名称空间。数据属性是 HTML5 中的新特性。例如,“
data-role
”是role
属性的默认名称空间。如果你想全局覆盖默认名称空间,你可以覆盖$.mobile.ns
选项。举例:
// Set a custom namespace $.mobile.ns = "jqm-";
因此,所有 jQuery Mobile data-*属性都需要前缀“
data-jqm-
”。例如,“??”属性现在变成了“??”。重要提示:如果您更新默认名称空间,您将需要更新 jQuery Mobile CSS 文件中的一个 CSS 选择器:
`// Original CSS for default namespace:
.ui-mobile [data-role=page],
.ui-mobile [data-role=dialog],
.ui-page {..}// Updated CSS for the new namespace "jqm-":
.ui-mobile [data-jqm-role=page],
.ui-mobile [data-jqm-role=dialog],
.ui-page {..}`为什么要覆盖默认名称空间?
首先,如果您正在设计一个包含 HTML5 data-*属性的 JavaScript 框架,W3C 建议您包含一个钩子,允许开发人员定制名称空间,以避免与第三方框架冲突。每当您遇到与另一个第三方框架的名称空间冲突时,您将需要更改您的默认名称空间。
-
page.prototype.options.addBackBtn(boolean, default: false)”
如果您希望后退按钮出现在整个应用中,请将此选项设置为
true
。jQuery Mobile 中的后退按钮是一个智能小部件。只有当历史堆栈中有页面可供返回时,它才会出现。举例:
$.mobile.page.prototype.options.addBackBtn = true;
-
page.prototype.options.keepNative(string, default:
:jqmData(role='none '),:jqmData(role='nojs ')"
如果您想防止自动初始化而不将
data-role="none"
添加到您的标记中,您可以定制用于防止自动初始化的keepNative
选择器。例如,为了防止框架初始化所有的选择和输入元素,我们可以更新这个选择器。举例:
$.mobile.page.prototype.options.keepNative = "select, input";
-
pageLoadErrorMessage(string, default: “Error Loading Page”)
Ajax 页面请求加载失败时出现的错误响应消息。
-
subPageUrlKey(string, default: “ui-page”)
用于引用小部件生成的子页的 URL 参数。子页面 URL 的一个例子是“nested-list.html&ui-page = Movies-3”。嵌套列表视图是一个特殊的小部件,它将每个列表分割成单独的子页面。例如,前面显示的 URL 有一个“Movies”子列表,jQuery Mobile 将其转换为自己的子页面,以容纳深层链接引用。如果需要重命名这个 URL 参数,可以用
$.mobile.subPageUrlKey
来更改。 -
touchOverflowEnabled(boolean, default: false)
为了实现具有本地动量滚动的真正的固定工具栏,浏览器需要支持位置:固定或溢出:自动。幸运的是,WebKit (iOS5)的新版本开始支持这种行为。默认情况下,很可能会启用该选项。在此之前,我们可以通过将此配置选项设置为 true 来启用此行为。
-
$.mobile.changePage()
changePage 函数处理从一个页面转换到另一个页面的所有细节。
用法
$.mobile.changePage( toPage, [options] )
自变量
toPage
(sting 或 jQuery 集合)。要转换到的页面。toPage
(字符串)。文件 URL(“contact . html”)或内部元素的 ID(“contact”)。toPage
(对象)。一个 jQuery 集合对象,包含一个页面元素作为其第一个参数:$("#contactPage ")
options
(对象)。配置 changePage 请求的一组键/值对。所有设置都是可选的。allowSamePageTransition
(布尔型,默认值:false)。changePage 方法将忽略转换到同一页面的请求。将此选项设置为true
以允许同页转换。changeHash
(布尔,默认:true
)。当页面更改完成时,将散列更新为 toPage 的 URL。data
(字符串或对象,默认:undefined
)。发送到 Ajax 页面请求的数据。dataUrl
(字符串,默认:toPage
URL)。设置要在浏览器的位置字段中显示的 URL。fromHashChange
(布尔型,默认值:false)。指示 changePage 是否来自 hashchange 事件。fromPage
(字符串,默认:$.mobile.activePage
)。指定“从”页。pageContainer
(jQuery 集合,默认:$.mobile.pageContainer
)。指定页面加载后应包含的元素。reloadPage
(布尔型,默认:false
)。强制重新加载页面,即使它已经在页面容器的 DOM 中。reverse
(布尔型,默认:false
)。以指示过渡应该向前还是向后。默认转换是向前。role
(字符串,默认:page
)。显示页面时要使用的数据角色值。对于对话框,使用“对话框”。showLoadMsg
(布尔型,默认:true
)。请求页面时显示加载消息。transition
(字符串,默认:$.mobile.defaultTransition)。申请变更页面的过渡。默认过渡是slide
。type
(字符串,默认:get
)。指定方法("get
或"post”) to use when making a page request.
)
例#1:
`//Transition to the "contact.html" page.
$.mobile.changePage( "contact.html" );Contact Us`
例 2:
`// Transition to the internal "#contact" page with a reverse "pop" transition.
$.mobile.changePage( ”#contact”, { transition: "pop", reverse: true } );Contact`
例三:
`/* Dynamically create a new page and open it */
// Create page markup
var newPage = $("");
Hi
Hello Again!// Add page to page container
newPage.appendTo( $.mobile.pageContainer );// Enhance and open new page
$.mobile.changePage( newPage );` -
$.mobile.hidePageLoadingMsg()
移除或隐藏页面加载信息(
$.mobile.loadingMessage
)。默认加载消息是“正在加载”,这也是可配置的。要显示加载信息,请参见$.mobile.showPageLoadingMsg().
举例:
// Remove the loading message $.mobile.hidePageLoadingMsg();
-
$.mobile.loadPage()
loadPage 函数将页面加载到当前页面的 DOM 中并增强它。该方法也作为数据属性公开,可以附加到链接或按钮上(参见“数据属性”一节中的“数据预取”)。
用法
$.mobile.loadPage( url, [options] )
自变量
url
(蛰)。要加载的页面。url
(字符串)。文件 URL(“contact . html”)。
options
(对象)。配置 changePage 请求的一组键/值对。所有设置都是可选的。data
(字符串或对象,默认:未定义)。发送到 Ajax 页面请求的数据。loadMsgDelay
(数字(毫秒),默认为 50)。在显示加载消息之前添加手动延迟。这种延迟允许框架在没有加载消息的情况下加载缓存的页面。PageContainer
(jQuery 集合,默认:
$.mobile.pageContainer)。加载后应包含页面的元素。reloadPage
(布尔型,默认:false)。强制重新加载页面,即使它已经在页面容器的 DOM 中。role
(字符串,默认:@data-role 属性)。用于加载页面的数据角色。默认值是在元素上定义的@data-role 属性。showLoadMsg
(布尔型,默认为:真)。请求页面时显示加载消息。type
(字符串,默认:“get”)。指定发出页面请求时使用的方法(“get"
或"post"
。
例子:
`// Dynamically load a page and transition to it.
$.mobile.loadPage("page1.html" );$.mobile.changePage("#page1" ); // data-url value`
-
$.mobile.showPageLoadingMsg()
显示页面加载信息(
$.mobile.loadingMessage
)。举例:
// Show the page loading message $.mobile.showPageLoadingMsg();
-
$.mobile.silentScroll(number)
垂直滚动页面。在这个框架中,每当页面被恢复时,
silentScroll
就会被调用。例如,当你点击后退按钮时,silentScroll
方法在显示前一页之前被触发,并将恢复前一页的滚动位置。重点将放在触发初始转换的组件上。在silentScroll
期间scrollstart
和scrollstop
事件不会被触发。举例:
`// Hide the iOS address bar
$.mobile.silentScroll(0);// Scroll down 400 pixels
$.mobile.silentScroll(400);` -
$.jqmData()
这是 jQuery
.data()
方法的移动版本。 1 该方法提供了$.data()
中的所有功能,并确保使用 jQuery Mobile 的数据命名空间($.mobile.ns
)设置和检索所有数据。例子:
`// Find all pages (data-role="page") in the DOM via a selector.
var $pages = $( ":jqmData(role='page')" );// Find the theme (data-theme) for the first page
var firstPage = \(pages.first(); var theme = **\).jqmData**( firstPage, "theme" );` -
$.jqmHasData()
这是 jQuery
.hasData()
方法的移动版本。 2 该方法提供了$.hasData()
中的所有功能,并确保使用 jQuery Mobile 的数据命名空间($.mobile.ns
)检索所有数据。例子:
// Does a theme exist for the first page var hasTheme = $.jqmHasData( firstPage, "theme" );
-
$.jqmRemoveData()
这是 jQuery
.removeData()
方法的移动版本。 3 该方法提供了$.removeData()
中的所有功能,并确保使用 jQuery Mobile 的数据命名空间($.mobile.ns
)删除所有数据。例子:
`// Set data on the first page
$.jqmData(firstPage, "testData", "testValue");// Remove the data from the first page
$.jqmRemoveData( firstPage, "testData" );` -
mobileinit
当 jQuery Mobile 初始化时,它会在
document
对象上触发一个mobileinit
事件。您可以绑定到mobileinit
事件,并将覆盖应用到 jQuery Mobile 的默认配置设置。关于绑定到mobileinit
事件的例子,请参考“配置 jQuery Mobile”一节。 -
pagebeforechange
这是页面更改期间触发的第一个事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。您可以通过调用事件上的
preventDefault
来取消页面更改。此外,您可以通过检查和更新数据对象来覆盖页面更改。作为第二个参数传递的数据对象包含以下属性:toPage
(字符串)。文件 URL 或 jQuery 集合对象。这与传递给$.mobile.changePage().
的参数相同options
(对象)。这些是通过to $.mobile.changePage
的相同选项。
举例:
`$( document ).bind( "pagebeforechange", function( e, data ) {
console.log(“Change page starting...”);// Get the page
var toPage = data.toPage;// Get the page options
var options = data.options;// Inspect toPage or override options (redirect)…
// Prevent a page change
e.preventDefault();
});` -
pagechange
这是页面更改成功后触发的最后一个事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:
-
toPage
(字符串)。文件 URL 或 jQuery 集合对象。这与传递给$.mobile.changePage()
的参数相同。 -
options
(object). These are the same options that were passed to$.mobile.changePage.
举例:
$( document ).bind( "pagechange", function( e, data ){ console.log(“Change page successfully completed...”); var toPage = data.toPage; var options = data.options; });
-
-
pagechangefailed
如果页面更改失败,将触发此事件。这个事件的回调传递了两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:
-
toPage
(字符串)。文件 URL 或 jQuery 集合对象。这与传递给$.mobile.changePage().
的参数相同 -
options
(object). These are the same options that were passed to$.mobile.changePage
.举例:
$( document ).bind( "pagechangefailed", function( e, data ){ console.log(“Page change failed...”); });
-
-
pagebeforeload
这是页面加载期间触发的第一个事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。如果您愿意,可以手动处理加载逻辑。为此,您必须在事件上调用
preventDefault()
,并在数据对象中包含的延迟对象引用上调用resolve()
或reject()
。作为第二个参数传递的数据对象包含以下属性:-
url
(字符串)。发送给$.mobile.loadPage()
的相对 URL。 -
absUrl
(字符串)。URL 的绝对引用。 -
dataUrl
(字符串)。实际存储在页面的 data-url 属性中的 URL 版本。此 URL 显示在浏览器的位置字段中。 -
deferred
(对象)。调用preventDefault()
来手动处理页面加载的回调函数必须调用这个对象上的resolve()
或reject()
,这样changePage()
请求才能继续处理。 -
options
(object). This is the same options argument that was passed to$.mobile.loadPage()
.举例:
`$( document ).bind( "pagebeforeload", function( e, data ){
console.log("Page load starting…");// Let the framework know we're manually loading the page
e.preventDefault();// Manually load the document and insert it into the DOM
var response = manuallyLoadPage();if (response.status = "success") {
// Call resolve passing in the url, options, and jQuery
// collection object containing the DOM element for the page
data.deferred.resolve( data.absUrl, data.options, response.page);
} else {
// The load failed, call reject
data.deferred.reject( data.absUrl, data.options );
}
});`
-
-
pageload
该事件在页面成功加载到 DOM 后触发。向该事件的回调传递两个参数。第一个是事件,第二个是数据对象。作为第二个参数传递的数据对象包含以下属性:
-
url
(弦)。发送给$.mobile.loadPage
的相对 URL。 -
absUrl
(字符串)。URL 的绝对引用。 -
dataUrl
(字符串)。实际存储在页面的 data-url 属性中的 URL 版本。此 URL 显示在浏览器的位置字段中。 -
options
(object). This is the same options argument that was passed to$.mobile.loadPage()
.举例:
$( document ).bind( "pageload", function( e, data ){ console.log("Page successfully loaded into DOM..."); });
-
-
页面加载失败
-
This event is triggered if the page load fails. During this process, the framework will display a page failed message and call
reject()
on the deferred object. Callbacks can prevent this default behavior from executing by callingpreventDefault()
on the event.举例:
$( document ).bind( "pageloadfailed", function( e, data ){ console.log("Page load failed..."); });
-
pagebeforecreate
在页面更改期间初始化页面时触发。此事件发生在页面容器插入 DOM 之后,但在页面增强之前。这是在框架增强页面之前预解析标记的首选位置。例如,在这种情况下,您可以动态地创建和添加新的页面小部件,或者修改现有的数据属性。
举例:
$( "#to-page-id" ).live( "pagebeforecreate", function(){ console.log( "Pre-parse the markup before the framework enhances the widgets" ); });
-
pagecreate
在页面更改期间正在初始化的页面上触发。这是框架初始化所有页面插件时触发的事件。如果您创建自定义页面插件,这是初始化它们的首选位置。
举例:
`$( "#to-page-id" ).live( "pagecreate", function(){
console.log("Page plugins are being initialized...");// Initialize custom plugins
(":jqmData(role='my-plugin')" ).myPlugin();
});` -
pageinit
在增强完成后正在初始化的页面上触发。页面现在处于 DOM 就绪状态。
举例:
$( "#to-page-id" ).live( "pageinit", function(){ console.log(“The page has been enhanced...”); // Attach event handlers or run other jQuery code... });
-
pagebeforehide
过渡开始时在“从”页面触发。该事件发生在
pagebeforeshow
事件之前。仅当页面更改请求有关联的“发件人”页面时,才会触发此事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:nextPage
(对象)。一个 jQuery 集合对象,包含我们要转换到的页面元素。
举例:
$( "#from-page-id" ).live( "pagebeforehide", function( e, data ){ console.log( "The page transition is just starting..." ); });
-
pagebeforeshow
在页面增强之后,页面转换开始之前,在“到”页面上触发。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:
-
prevPage
(object). A jQuery collection object containing the page element we are transitioning from.举例:
$( "#to-page-id" ).live( "pagebeforeshow", function( e, data ){ console.log( "The page transition is just starting..." ); });
-
-
pagehide
在转换完成之后和
pageshow
事件之前,在“from”页面上触发。仅当页面更改请求有关联的“发件人”页面时,才会触发此事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:-
nextPage
(object). A jQuery collection object containing the page element we are transitioning to.举例:
$( "#from-page-id" ).live( "pagehide", function( e, data ){ console.log( "The page transition is complete!" ); });
-
-
pageshow
在转换完成和隐藏“从”页面后,在“到”页面上触发。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:
-
prevPage
(object). A jQuery collection object containing the page element we are transitioning from.举例:
$( "#to-page-id" ).live( "pageshow", function( e, data ){ console.log( "The page transition is complete!" ); });
-
-
trigger(“create”)
我们可以触发这个事件来自动增强页面上的所有新元素。该事件在页面容器上触发。
举例:
`// Add two new buttons to the page
\(( '<button id="b2">Button2</button>' ).insertAfter( "#b1" ); \)( '' ).insertAfter( "#b2" );// Enhance the new buttons on the page
$.mobile.pageContainer.trigger( "create" );` -
$.mobile.activePage
获取当前活动或可见的页面或对话框元素。活动页面被分配了由
$.mobile.activePageClass
指定的 CSS 类。 -
$.mobile.firstPage
这是页面容器(
$.mobile.pageContainer
)中定义的第一个页面。例如,当不存在location.hash
值或$.mobile.hashListeningEnabled
被禁用时,将显示$.mobile.firstPage
。例如,在多页文档中,默认情况下最初会显示$.mobile.firstPage
。 -
$.mobile.pageContainer
所有页面所在的 HTML 容器。在 jQuery Mobile 中,
body
元素是包含所有页面的容器。所有 Ajax 加载的页面和多页面文档的所有内部页面都将存在于页面容器中。 - Tweets
我还在主 jQuery Mobile CSS 文件之前导入了新的 custom-theme.css 文件。对于我们的第二个测试,我想在一个删除按钮上应用我们新的“v”样本。对于这个测试,我创建了一个对话框来确认潜在的危险动作,并用我们新的红色渐变风格主题设计了删除按钮(参见图 7–13 和清单 7–13 中的相关代码)。
图 7–13。 红色删除按钮用于删除动作
清单 7–13。 带“v”的删除按钮样本(ch7/custom1.html)
`
Are you sure?
<a href="#home" data-role="button" data-theme="v">Delete
Cancel
最后,当您创建新的样本时,在颜色编码的样式指南中记录您的自定义样式会很有帮助,这样组织中的所有设计人员和开发人员都会熟悉它们的用法和样式。
提示: CSS 渐变生成器 3 是可以自动生成你的渐变语法并帮助简化步骤 4 的工具。
泰晤士报
ThemeRoller 4 是一个基于 web 的工具,它帮助自动为 jQuery Mobile 生成新的基于 CSS 的主题。这是一个非常有用的工具,因为它允许您在左窗格中更新配色方案,并在右窗格中预览实际 jQuery Mobile 布局的结果(参见图 7–14)。
图 7–14。 主题人物
3 见[www.westciv.com/tools/gradients/](http://www.westciv.com/tools/gradients/)
或[
gradients.glrzad.com/](http://gradients.glrzad.com/).
4 见[
jquerymobile.com/themeroller](http://jquerymobile.com/themeroller).
样本和全局设置
在左侧窗格中出现的“全局”选项卡下,您可以快速调整全局应用于所有色板的 CSS 属性。在这里,您可以调整字体系列、活动状态颜色、拐角半径、图标和阴影(参见图 7–15)。
图 7–15。 全局主题设置
“全局”选项卡旁边是样本特定选项卡(a-z)。您可以在此添加、编辑或删除主题中的样本(参见图 7–15)。
预览检查器和快速观看栏
为了更容易地构建自定义主题,预览面板顶部有两个独特的工具:预览检查器和快速观看栏。
预览检查器是一个可以“开”或“关”的开关(见图 7–16)。打开开关后,单击预览窗格中的元素将自动在左窗格中显示其可编辑属性。当您需要快速编辑样式时,这将是一个宝贵的时间节省。
图 7–16。 预览检查器和快速观看栏
快速观察条是出现在检查器右侧的一系列颜色(参见 Figure 7–16)。这是一个强大的工具,允许您将任何颜色拖放到预览页面中的元素或左窗格中的颜色属性上。快速观察栏下面是两个滑块,用于调整调色板的亮度和饱和度。此外,最近选择的颜色将显示在色谱的右侧,以便快速重复使用。
Adobe Kuler 集成
当你需要从头开始创建一个调色板时,这可能是一个挑战。为了帮助简化这个过程,ThemeRoller 内置了 Adobe 的 Kuler 1 集成(参见图 7–17)。
图 7–17。 Adobe 的 Kuler App
Kuler 是一个允许人们创建、分享和评价调色板的网站。要查看 Kuler 中可用的调色板,请单击出现在快速观察栏上方的“Adobe Kuler”链接。当 Kuler 应用打开时,搜索过滤器会出现在左侧窗格中,允许您按最新、热门、评级或自定义搜索进行过滤。当您找到感兴趣的颜色时,只需将该颜色拖放到预览窗格中的元素上。
开始使用
为了便于比较,我将在 ThemeRoller 中创建一个红色的强调色板,看看这种体验与我们在上一节中创建的手动色板相比如何。在本练习中,我将使用新的红色强调色板覆盖 jQuery Mobile 的默认“e”色板。在 ThemeRoller 中,要更新现有主题,需要执行以下步骤:
5 见[
kuler.adobe.com](http://kuler.adobe.com).
图 7–20。滚轮的红色删除按钮
总结
jQuery Mobile 主题框架是一个面向对象的 CSS3 框架,它是轻量级的、可定制的,可以跨所有浏览器呈现统一的设计。在这一章中,我们讨论了主题框架的基础,并回顾了 jQuery Mobile 中包含的五个样例。
我们还回顾了将主题分配给组件的三种方式。虽然所有组件都可以使用data-theme
属性显式设置它们的主题,但是大多数组件也有默认主题,并且可以从父容器继承它们的主题。我们看到了每个主题的例子,并回顾了主题应用于组件的优先顺序。
最后,我们看到了如何创建我们自己的定制样本。无论你是需要创建一个更丰富的设计,还是需要创建一个与你的公司品牌紧密匹配的设计,主题框架对于所有的需求都足够灵活。我们回顾了可用于创建自定义样本的两个选项,并查看了每个选项的分步示例。我们看到手动方式让我们完全控制了我们的布局,jQuery Mobile 的新 ThemeRoller 提供了一个更有效、更直观的工作环境。
在下一章中,我们将深入了解 jQuery Mobile API。我们将学习如何配置 jQuery Mobile,还将回顾 API 的核心方法、事件、属性和数据属性。
八、jQuery Mobile API
所有编写良好的框架都允许开发人员扩展和覆盖默认的配置设置。此外,它们提供了方便的方法来帮助简化您的代码。jQuery Mobile 包括一个相当广泛的 API,它公开了这些便利的特性。首先,我们将看看如何配置 jQuery Mobile。我们将回顾 jQuery Mobile 中的每个可配置特性,突出显示其默认设置,并展示 API 如何允许您配置每个选项。然后,我们将探索 jQuery Mobile 公开的最流行的方法、页面事件和属性。当您需要以编程方式更新移动 Web 应用时,这些 API 特性非常有用。最后,我们将查看一个列出所有 jQuery Mobile 数据属性的排序表。对于每个属性,我们将包括其增强组件的简短描述、示例和图表。
配置 jQuery Mobile
当 jQuery Mobile 初始化时,它会在document
对象上触发一个mobileinit
事件。您可以绑定到mobileinit
事件,并将覆盖应用到 jQuery Mobile 的($.mobile
)默认配置设置。此外,您可以用附加的行为和属性来扩展 jQuery Mobile。例如,有两种配置 jQuery Mobile 的方法,如下例所示。您可以通过 jQuery 的extend
方法或者单独覆盖这些属性。
例子:
`// Configure properties via jQuery's extend method
\(( document ).bind( "mobileinit", function(){
\).extend( $.mobile, {
// Override loading message
loadingMessage: "Loading...",
// Override default transition from “slide” to “pop”
defaultTransition: "pop"
});
});
// Configure properties individually
\(( document ).bind( "mobileinit", function(){
\).mobile.loadingMessage = "Initializing";
$.mobile.defaultTransition = "slideup";
});`
自定义脚本放置
由于执行 jQuery Mobile 时会立即触发mobileinit
,所以您需要将您的定制脚本放在 jQuery Mobile JavaScript 文件之前。
举例:
`
<script type=”text/javascript” src="custom-scripts-here.js">
可配置的 jQuery Mobile 选项
以下是可配置的$.mobile
选项,您可以在自定义 JavaScript 中覆盖这些选项。
方法
jQuery Mobile 提供了一套方法,当您需要以编程方式更新移动 Web 应用时,这些方法非常有用。
<sup>1</sup> [
api.jquery.com/jQuery.data/](http://api.jquery.com/jQuery.data/)
<sup>2</sup> [
api.jquery.com/jQuery.hasData/](http://api.jquery.com/jQuery.hasData/)
<sup>3</sup> [
api.jquery.com/jQuery.removeData/](http://api.jquery.com/jQuery.removeData/)
事件
jQuery Mobile 还公开了几个事件,当您需要在移动 Web 应用中的页面更改期间以编程方式应用预处理或后处理时,这些事件会很有帮助。在这一节中,我们将回顾您可以在自己的代码中绑定的 jQuery Mobile page 事件的完整列表。对于 jQuery Mobile events 的介绍,让我们从一个图表开始(图 8-1 )。该图显示了 jQuery Mobile 中发生的主要页面事件,并有助于描述页面更改生命周期中每个事件的顺序。
图 8-1。 jQuery 手机页面事件
现在我们已经看到了页面变更生命周期中页面事件的触发顺序,让我们来看看每个特定事件的详细信息。
事件概述
页面变更事件
当您导航到另一个页面时,文档上会自动触发页面更改事件。在内部,当调用$.mobile.changePage
方法时,这些事件被触发。在此过程中,将触发两个事件。第一个触发的事件是pagebeforechange.
。下一个触发的事件取决于页面更改的状态。当页面更改成功时,将触发 page change 事件,如果页面更改失败,将触发pagechangefailed
事件。
页面加载事件
当框架将页面加载到 DOM 中时,页面加载事件在文档上被触发。以编程方式,当调用$.mobile.loadPage
时,该事件被触发。在这个过程中,loadPage()将触发两个事件。第一个是pagebeforeload
,第二个事件是成功(pageload
)或失败(pageloadfailed
)事件。
页面初始化事件
在 jQuery Mobile 增强页面之前和之后,页面初始化事件都会在页面上触发。您可以绑定到这些事件,在框架增强页面之前预解析标记,或者在之后设置 DOM ready 事件处理程序。这些事件在页面的生命周期中只触发一次。
页面过渡事件
在页面转换期间,页面转换事件在“从”和“到”页面上触发。您可以绑定到这些事件来观察页面何时显示或从视图中移除。
提示:jQuery Mobile 团队已经创建了一个有用的书签小程序,允许您从浏览器控制台查看页面事件历史(参见图 8-2 )。当您浏览 jQuery Mobile 应用时,您将能够通过页面、URL 和时间戳查看事件的历史。要安装,请转到 jQuery Mobile event logger 页面 4 并按照它们的说明安装书签。
图 8-2。 页面事件记录器控制台
触发事件
在构建动态页面时,触发 jQuery Mobile 页面事件会很有帮助。例如,如果您向页面添加几个新组件,您可以调用 create 事件来一次增强页面上的所有新部件。
4 见[
jquerymobile.com/test/tools/log-page-events.html](http://jquerymobile.com/test/tools/log-page-events.html).
属性
jQuery Mobile 还公开了一组公共可用的属性,因此您不必编写自己的 jQuery 选择器来访问公共组件。
数据属性
jQuery Mobile 的数据属性提供了用简单的 HTML 标记增强和配置移动应用的能力。所有数据属性的完整列表,按字母顺序排列,说明和示例如下(见表 8-1 )。
总结
在本章中,我们看到了如何配置 jQuery Mobile,并回顾了许多可用于构建更多动态页面的常见 API 特性。无论您是需要全局更改默认转换,还是希望在所有页面上显示后退按钮,jQuery Mobile 都允许我们重新配置许多常见设置。我们还回顾了 jQuery Mobile 公开发布的许多流行的方法、事件和属性。当您需要以编程方式更新移动 Web 应用时,这些 API 特性非常有用。最后,我们看到了所有 jQuery Mobile 数据属性的完整列表。希望这个列表可以为您在快节奏的 jQuery Mobile 项目中工作提供一个快速的参考。每个属性包括一个简短的描述,例子和数字。
在下一章中,我们将深入探讨如何有效地使用服务。我们将看到如何将 jQuery Mobile 页面与客户端和服务器端集成解决方案集成。
九、服务整合策略
构建 Web 应用时,加载数据有两种主要的访问策略。有传统的服务器端访问策略和 Web 2.0 的客户端访问策略。在这一章中,我们将展示将 jQuery Mobile 与这两种访问策略集成的例子,并讨论每种策略的优点。jQuery Mobile 很好地集成了这两种策略,因此,您可以选择最适合您的应用需求的访问策略。
首先,我们将展示两个客户端集成示例。随着社交媒体的流行,我们的第一个例子将演示如何与 Twitter 的 RESTful API 集成。RESTful APIs 是轻量级的 web 服务,由于其简单的设置和灵活的响应类型(JSON、XML),通常比传统的 web 服务更受欢迎。在我们的 Twitter 示例之后,我们将创建我们自己的 RESTful API,允许用户注册免费电影奖品。这个注册示例将有助于展示我们从 jQuery Mobile 应用向 RESTful API 提交内容的能力。此外,这个例子将让您熟悉如何在服务器端设置 RESTful API。
然后,我们将过渡到服务器端集成策略,并实现一个获取数据的用例以及另一个发布数据的用例。为了进行比较,我们将把客户端注册示例重新实现为服务器端解决方案。当使用服务器端模型-视图-控制器(MVC)访问策略获取数据时,您可能会惊讶地发现我们页面标记变得更加整洁。
最后,随着地理定位和地图视图的流行,我们将看到如何将 jQuery Mobile 与 HTML5 地理定位 API 和 Google Maps 集成。
客户端与 RESTful 服务的集成
大多数社交媒体网站都有一个公共 API 来访问它们的数据。Twitter、 1 LinkedIn、 2 和脸书 3 集成在 Web 上非常常见,RESTful 集成是它们中每一个的常见访问策略。在这一节中,我们将把 jQuery Mobile 与两个不同的 RESTful APIs 集成在一起,这样我们就可以看到这个策略在 jQuery Mobile 中运行得有多好。
客户端 Twitter 与 Ajax 的集成
在我们的第一个客户端示例中,我们将把 jQuery Mobile 与 Twitter 的 RESTful API 集成在一起。Twitter 是一个非常受欢迎的社交媒体网站,允许用户发送或“推特”关于主题、事件或随机观点的简短消息。在我们的电影应用中,允许用户实时搜索 Twitter 以获得他们可能感兴趣的电影的反馈可能是有价值的。例如,除了查看其他人对某部电影的评论,我们可能希望提供一个方便的 Twitter 链接,显示关于这部电影的最新推文。在我们的用户评论页面上,我们在标题中添加了一个 Twitter 按钮,用户可以点击它来查看关于这部电影的最新推文(参见图 9–1 及其在清单 9–1 中的相关代码)。
①见 http://dev.twitter.com/console
。
2 见[
developer.linkedin.com/community/apis](http://developer.linkedin.com/community/apis)
。
3 见[
developers.facebook.com/](http://developers.facebook.com/)
。
图 9–1。 影评页面页眉的推特按钮
清单 9–1。 电影评论页面页眉的 Twitter 按钮(ch9/reviews.html)
`<div data-role="page" id="reviewsPage">
Reviews
<a href="twitter.html" id="twitterBtn" class="ui-btn-right"
data-icon="custom" data-iconpos="notext">
... `
当用户点击 Twitter 按钮时,我们将在 Twitter 上搜索当前电影的最新推文,并将结果加载到我们的 Twitter 结果页面上(参见图 9–2 及其在清单 9–2 中的相关代码)。
图 9–2。 推特结果页面
清单 9–2。 推特结果页面(ch9/twitter.html)
`<div data-role="page" id="twitterPage">
...
<ul id="tweet-list" data-role="listview" data-inset="true">
`
在清单 9–2 中显示的tweet-list
id 是我们的占位符,我们将在这里追加我们的 Twitter 搜索结果。Twitter 的搜索 API 返回许多数据元素,然而,我们只对 tweet 文本、发布 tweet 的用户以及用户的个人资料图像感兴趣。
提示:要查看 Twitter 的搜索 API 中所有可用的数据元素,在浏览器中启动这个字符串“[
search.twitter.com/search.json?q=xmen](http://search.twitter.com/search.json?q=xmen)
”。这是基本的搜索 API,其中“q
”参数的值是我们的可搜索关键字。在这种情况下,我们在 Twitter 上搜索任何包含关键字“xmen
”的推文。
提示:大多数浏览器以无格式的样式显示 JSON 响应,这可能非常不友好:
作为替代,Firefox 有一个 JSON 查看器插件 4 ,它以更结构化的格式格式化 JSON 响应:
同样,如果你需要验证 JSON,JSONLint 5 可以是一个有用的工具。
jQuery Mobile 内置了 Ajax 支持,这使得 RESTful 集成更加简单,不依赖于第三方 JavaScript 框架。这种支持来自 jQuery Mobile 扩展的 jQuery API 6 。在 jQuery 中,$。ajax 7 API 是 RESTful 集成的首选解决方案,因为它简单且具有灵活的配置选项(超时、缓存等)。).
4 见[
addons.mozilla.org/en-US/firefox/addon/jsonview/](https://addons.mozilla.org/en-US/firefox/addon/jsonview/)
。
5 见【http://jsonlint.com/】的。
6 见【http://jquery.com/】的。
7 见API . jquery . com/jquery . Ajax/
。
要将 jQuery Mobile 与 Twitter 的 RESTful API 集成,以下步骤是必要的(参见清单 9–3):
- 当点击 Twitter 按钮时,我们将首先显示 jQuery Mobile 活动指示器,这样用户就可以直观地意识到一个活动正在后台处理:
$( "#twitterBtn" ).bind( "click", function(e) { ** $.mobile.showPageLoadingMsg();**
- 接下来,我们将把 Twitter 结果页面加载到当前页面的 DOM 中。如果页面已经存在于 DOM 中,我们将重新加载并更新缓存的页面:
**$.mobile.loadPage("twitter.html", { reloadPage: true });**
- 在我们的 Twitter 页面得到增强之前,我们将向 Twitter API 发送一个 AJAX 请求来收集我们的搜索结果:
$(“#twitterPage”).live("**pagebeforecreate**", function(){ **$.ajax**({...
- 我们的
url
选项被配置为 Twitter 的 RESTful API,我们的搜索查询被配置为查找所有包含关键字“xmen”的 tweets:**url:** "http://search.twitter.com/search.json?q=xmen"
- 由于 Twitter API 存在于另一个域中,我们需要将我们的
dataType
选项设置为jsonp.
通常,跨域通信是不允许的,但是 JSONP 8 有助于促进跨域集成的可信方式:**dataType:** "jsonp"
- 最后,我们实现了我们的
success
回调来迭代搜索结果,为每一行创建一个列表项,并将新的标记附加到我们的列表容器中:
success: function( response ) {...
清单 9–3。 客户端 Twitter 集成(ch9/twitter.js)
`\(( "#reviewsPage" ).live( "pageinit", function(){
\)( "#twitterBtn" ).bind( "click", function(e) {
** $.mobile.showPageLoadingMsg();**
// Reload Twitter results page even if it's already in the DOM
** $.mobile.loadPage("twitter.html", { reloadPage: true });**
// Prevent default click behavior
return false;
});
});
\(( #twitterPage" ).live("pagebeforecreate", function(){
**\).ajax**({
url: "http://search.twitter.com/search.json?q=xmen",
dataType: "jsonp",
success: function( response ) {
* // Generate a list item for each tweet*
var markup = "";
$.each(response.results, function(index, result) {
var $template = $('
* // Append the Tweet items into our Tweet list and refresh the
// entire list.*
$( "#tweet-list" ).append(markup).listview( "refresh", true );
// Transition to the Twitter results page.
$.mobile.changePage( $("#twitterPage") );
},
});
});
In this example, we have chosen to load the Twitter results on demand when the user
clicks on the Twitter button. Alternatively, you may pre-fetch the Twitter data so users
can see the Twitter results instantly when the button is clicked. To set up this
strategy, add the data-prefetch attribute on the Twitter button:
<a href="twitter.html" id="twitterBtn" class="ui-btn-right" data-icon="custom" data-
iconpos="notext" data-prefetch>`
8 见[
en.wikipedia.org/wiki/JSONP](http://en.wikipedia.org/wiki/JSONP)
。
现在页面的改变可以通过按钮的默认点击行为来处理,这样我们就可以在 Twitter 结果被添加到列表后,删除这个按钮和$.mobile.changePage()
调用的自定义点击处理程序。
此外,在生产用例中,您将希望在$.ajax
方法上配置timeout
和error
回调,以处理任何无响应或不可用的 API。例如,如果 Twitter API 没有响应,通知用户可能会有所帮助:
`timeout: 6000, // Timeout after 6 seconds
error: function(jqXHR, textStatus, errorThrown) {
$.mobile.hidePageLoadingMsg();
* // Show error message*
\(( "<div class='ui-loader ui-overlay-shadow ui-body-e
ui-corner-all'><h1>"+ **\).mobile.pageLoadErrorMessage** +"" )
.css({ "display": "block", "opacity": 0.96, "top": 100 })
.appendTo( **\(.mobile.pageContainer** )
.delay( 800 )
.fadeOut( 1000, function() {
\)( this ).remove();
});
}`
使用 Ajax 的客户端表单发布
前面的例子是一个向 Twitter 的 API 发送 GET 请求的用例。从 API 读取时,GET 请求非常常见,当没有指定时,$.ajax
方法将默认为这个type
。在下一个例子中,我们将创建自己的 RESTful API,允许用户发送 POST 请求。让我们创建一个 API,这样用户就可以注册奖品。我们的用户界面将由一个简单的表单组成,只需要一个电子邮件地址(参见图 9–3 和清单 9–4 中的相关代码)。
图 9–3。Ajax 客户端岗位登记表
清单 9–4。Ajax 客户端发布登记表(ch9/register-client.html)
<div data-role="page" **id="registrationPage"** data-theme="d"> <div data-role="header"> <h1>Registration</h1> </div>
`
<form id="register" method="post">
<input type="email" name="email" id="email" placeholder="Email"
required />
提示:电子邮件地址的输入字段包括三个新的 HTML5 属性。type=”email”
字段提供了两个好处。首先,当字段获得焦点时,它会提示 QWERTY 键盘几个有用的电子邮件键(参见 Figure 9–3)。其次,它还将在提交表单时验证该字段是否包含有效的电子邮件地址。例如,在较新的桌面浏览器中,如果用户输入了无效的电子邮件,系统会提示用户以下消息:
此外,当用户提交时,required
属性将断言 email 字段不为空。如果为空,用户将收到以下警告:
最后,placeholder
属性将向输入字段添加提示文本。虽然这些特性很有帮助,但并不是所有的特性都被今天的浏览器所支持。Peter-Paul Koch 有一个有用的站点 9 ,它显示了所有可用的输入属性及其相关的浏览器支持。
为了在客户端处理表单提交,我们将在提交按钮上附加一个事件监听器。要向我们的 RESTful API 提交 POST 请求,必须执行以下步骤(参见清单 9–5):
9 见[
www.quirksmode.org/html5/inputs_mobile.html](http://www.quirksmode.org/html5/inputs_mobile.html)
和
- 首先,我们需要拦截并覆盖默认的提交行为。现在我们准备通过 RESTful API 提交表单:
$("form").submit(function () {
- 其次,我们需要显示 jQuery Mobile 活动指示器,这样用户就可以直观地意识到活动正在后台处理:
$.mobile.showPageLoadingMsg()
- 接下来,我们用所有必需的选项设置我们的
$.ajax
请求:-
Our
url
option is configured to our new RESTful resource that was set up locally to handle the client-side registration:url:
"http://localhost:8080/jqm-webapp/rest/register"
我们一会儿将看看 RESTful 实现。
-
Next, we set the
type
option to POST. POST is the recommend type when creating new entities and it is slightly more secure than GET because it does not expose the data attributes as query string parameters on the URL:**type:** "POST
-
Again we set the
dataType
option tojsonp
because our RESTful API is also running on a separate domain from our client:dataType:``jsonp
-
The
jsonp
option defines the callback function that will handle the response:jsonp: "**jsoncallback**"
任何处理
jsonp
请求的 RESTful 资源都必须产生一个 JavaScript 响应。响应实际上是包装在 JavaScript 函数中的 JSON 数据。例如,我们的 RESTful API 的响应将包括成功注册的电子邮件地址,包装在回调函数中。这个回调函数的名称需要设置为我们的jsonp
选项的值:**jsoncallback**({"email":"BradPitt@gmail.com"})
-
data
选项包含我们想要发送给 RESTful 资源的数据。在这种情况下,我们将发送所有表单值,并用 jQuery 的serialize
方法:**data:** $**(**"form#register"**).**serialize**(),**
对它们进行 URL 编码 -
最后一个选项是我们的
success
处理程序。这将在我们收到来自 RESTful API 的成功响应后得到处理。在我们的例子中,我们将用户转发到一个感谢页面,并传递成功注册的电子邮件地址作为数据参数进行确认:success: function( response ) {$.mobile.changePage( “register- thanks.html”, { data: {"email": response.email}} ); }
-
清单 9–5。 使用 Ajax 的客户端 POST(ch9/register . js)
`\((“#registrationPage”).live("pageinit", function(){
\)("form").submit(function () {
** $.mobile.showPageLoadingMsg();**
$.ajax({
url: "http://localhost:8080/jqm-webapp/rest/register",
type: "POST",
** dataType:** "jsonp",
** jsonp:** "jsoncallback",
** data:** \(**(**"form#register"**).**serialize**(),**
**success:** function( response ) {
**\).mobile.changePage**( “register-thanks.html”,
{ data: {"email": response.email}} );
}
return false; // Prevent a form submit
});
});`
注册成功后,用户将被转到一个感谢页面,在这里我们向他们展示他们赢得的奖品以及奖品发送的电子邮件地址(参见图 9–4 及其在清单 9–6 中的相关代码)。
图 9–4。 用 Ajax 发布客户端帖子后的感谢页面
清单 9–6。 用 Ajax 客户端发布后的感谢页面(ch9/register-thanks.html)
`<div data-role="page" id="thanksPage" data-theme="d">
Thanks for registering. One FREE movie pass was just sent to:
提示:为你的网站设计导航策略时,为用户提供一些导航选项以避免死角是很重要的。在 jQuery Mobile 中,一个简单的解决方案是总是在标题栏中显示主页图标,并通过反向转换将其重定向回主页:
<a href="home.html" data-icon="home" data-iconpos="notext" data- direction="reverse"></a>
当我们执行changePage
调用时,我们还将电子邮件地址作为数据属性传递给了感谢页面。该数据属性被附加到页面的data-url
属性中:
data-url="/ch9/register-thanks.html?email=BradPitt%40gmail.com"
在感谢页面增强之前,我们获取该电子邮件地址并将其绑定到感谢页面的电子邮件占位符中(参见清单 9–7)。
清单 9–7。 将邮件附加到感谢页面(ch9/register.js)
`$("#thanksPage").live("pagebeforecreate", function(){
** var email = getParameterByName("email", \((this).jqmData("url"));**
** \)(".email").append(email);**
});
function getParameterByName(param, url) {
var match = RegExp('[?&]' + param + '=([^&]*)').exec(url);
return match && decodeURIComponent(match[1].replace(/+/g, ' '));
}`
服务器端处理注册的 RESTful 实现是用 Jersey 10 实现的,并部署在 Tomcat 11 上(参见清单 9–8)。
清单 9–8。【com.bmb.jqm.resource.RegisterResourse.java RESTful 资源办理注册
`@Path("/register")
public class RegisterResource {
** @Produces("application/x-javascript")**
public Response register(@QueryParam("jsoncallback")
@DefaultValue("jsoncallback") String callback,
@QueryParam("email") String email) {
Registration registration = new Registration();
registration.setEmail(email);
// Save registration...
// Return registration in response as jsonp
return Response.status(Response.Status.OK).entity(new
JSONWithPadding(registration, callback)).build();
}
}`
10 见[
jersey.java.net/](http://jersey.java.net/)
。
11 见[
tomcat.apache.org/](http://tomcat.apache.org/)
。
在浏览资源时,让我们回顾一下 Jersey 的注释:
@Path
注释定义了资源负责处理的路径。在这种情况下,RegisterResource 对象将处理发送到“*/rest/register”的所有请求。Jersey 在 web.xml 中配置,有两个配置项需要设置(参见清单 9–9)。首先,我们需要定义部署所有资源的包,其次,我们需要定义应该通过 Jersey 容器发送哪些 URL 模式。我们已经定义了所有 RESTful 资源都在包“com.bmb.jqm.resource
”中声明,我们将通过 Jersey 容器路由所有带有“/rest/*
”的 URL 路径。@Produces
注释定义了我们的响应的 MIME 类型。我们选择跨域公开我们的 RESTful API,这需要资源返回一个 JavaScript 响应。这允许客户端使用jsonp
请求访问 API。- register 方法接受两个输入参数。第一个是回调函数名。客户端可以发送回调函数的名称,但这不是必需的。如果没有提供,服务器会将回调名称默认为“
jsoncallback
”。最后一个参数是注册用户的电子邮件地址。 - 服务器现在可以处理注册并生成响应。在本例中,我们将返回一个响应,其中包含转换为 JSON 并包装在回调函数中的注册对象:
jsoncallback({"email":"BradPitt@gmail.com"})
清单 9–9。 球衣配置(web.xml)
<servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> ** <param-value>com.bmb.jqm.resource</param-value>** </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> ** <url-pattern>/rest/*</url-pattern>** </servlet-mapping>
正如我们所见,jQuery Mobile 与 RESTful API 集成得非常好。无论我们需要读取还是提交数据,内置的 jQuery 库都提供了在客户端管理 RESTful 生命周期的所有便利功能。
服务器端与 MVC 的集成
在这一节中,我们将把注意力集中在服务器端访问策略上。在 Web 上,一个非常常见的策略是集成模型-视图-控制器(MVC)框架。我们将看到两个 MVC 例子,它们在风格上与我们的客户端例子非常相似。在我们的第一个例子中,我们将把客户端注册用例转换成服务器端实现。这个例子将提供一个苹果对苹果的比较,说明如何在 jQuery Mobile 中使用客户端访问策略和服务器端访问策略实现相同的用例。在最后一个例子中,我们将看到如何实现从服务器获取数据的用例。
使用 MVC 的服务器端表单发布
为了便于比较,看一下我们的注册用例的服务器端实现是很有价值的。同样,我们将有一个注册表单,允许用户选择接收折扣或免费电影票(见图 9–5)。
图 9–5。MVC 服务器端岗位登记表
我们注册页面的页面标记与客户端示例中显示的非常相似,只是我们不打算覆盖表单提交流程。在我们的服务器端注册示例中,当用户点击注册按钮时,我们将让表单向我们的动作提交请求(参见清单 9–10)。
清单 9–10。 服务器端集成登记表(/web app/ch9/register-server . html)
`
Register
<form id="register" action="/jqm-webapp/mvc/register" method="post">
将我们的客户端示例(register-client.html)的注册页面与这个示例(register-server.html)的注册页面进行比较时,有什么突出的地方吗?最显著的区别是这个页面不需要定制 JavaScript。因此,我们的页面标记更加干净。
当提交表单时,POST 请求将被发送到我们的操作(/jqm-webapp/mvc/register
)中定义的路径。这个请求将由部署在 Tomcat 上的 Spring MVC 12 控制器在服务器端处理。在我们的 web.xml 文件中,我们配置了 servlet 映射,因此所有的"/mvc/*
" URL 都通过 Spring MVC 的 dispatcher servlet 进行路由(参见清单 9–11)。
清单 9–11。Spring MVC servlet-mapping 配置(/WEB-INF/web.xml)
<servlet> <servlet-name>jqm-webapp</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jqm-webapp</servlet-name> ** <url-pattern>/mvc/*</url-pattern>** </servlet-mapping>
从用户界面的角度来看,工作流与我们的客户端注册示例相同。表单被提交、处理,然后显示我们的感谢页面。处理请求并将其重定向到感谢页面的控制器代码如清单 9–12 所示。
12 见[
static.springsource.org/spring/docs/current/spring-frameworkreference/html/mvc.html](http://static.springsource.org/spring/docs/current/spring-frameworkreference/html/mvc.html)
。
清单 9–12。??【com.bmb.jqm.controller.RegisterController.java】春天 MVC 注册控制器
`@Controller()
public class RegisterController {
** @RequestMapping(method = RequestMethod.POST)**
public String enroll(@RequestParam("email")String email, HttpSession
session) {
// Save registration...
session.setAttribute("email", email);
** return "redirect:/mvc/register/thanks";**
}
** @RequestMapping(method = RequestMethod.GET)**
public String thanks() {
return "register-thanks";
}
}`
让我们在单步调试控制器时回顾一下 Spring MVC 注释:
@Controller
注释将类定义为可以处理请求的控制器。Spring MVC 配置了路径到类名的映射。例如,所有的"/register/
"请求将被分派给 RegisterController。这个配置是在 Spring MVC 的 dispatcher servlet 中设置的(参见清单 9–13)。@RequestMapping
注释定义了处理 POST 和 GET 请求的方法。当提交表单时,POST 请求将被发送到enroll
方法。thanks
方法将处理所有的 GET 请求。例如,我们在处理完表单后重定向到感谢页面,当感谢页面刷新时会触发thanks
方法。@RequestParam
注释将表单上提交的电子邮件地址绑定到我们的电子邮件输入参数。当调用 enroll 方法时,我们保存注册,将电子邮件地址置于会话中,并重定向到感谢页面(/jsp/register-thanks.jsp
)。
清单 9–13。 Spring MVC 路径到控制器映射配置(/we b-INF/jqm-WEB app-servlet . XML)
<!-- Enable controller mapping by convention. For example: /foo/* will map to FooController() --> <bean class="org.springframework.web.servlet.mvc.support.**ControllerClassNameHandlerMapping**" />
感谢页面的外观将与我们的客户端示例相同(参见 Figure 9–6)。
图 9–6。 服务器端发布后的感谢页面用 MVC
唯一的区别在于页面是如何生成的。该页面在服务器端生成为 JSP,电子邮件地址与 JSTL 表达式语法绑定在一起(参见清单 9–14)。动态生成页面不需要 JavaScript,与我们在客户端示例中看到的动态生成的感谢页面相比,这个标记更加简洁。
清单 9–14。 服务器端注册后的感谢页面(/jsp/register-thanks.jsp)
`
Thank You
Thanks for registering. One FREE movie pass was just sent to:
${email}
提交表单后需要注意的一个重要事项是,jQuery Mobile 管理浏览器地址栏中显示的 URL。例如,在服务器重定向到“/mvc/register/thanks
之后,浏览器 URL 仍然显示我们动作的路径(/jqm-webapp/mvc/register
)。如果您还没有为该路径实现 GET 请求处理程序,那么“感谢”页面上的“刷新”将导致 404,not found 错误。您有两种选择来处理这个问题:
-
最简单的解决方案是在控制器上为动作路径实现一个 GET 请求处理程序。我们的
RegisterController#thanks
方法处理 GET 请求,并将简单地刷新感谢页面,重新显示会话中存储的电子邮件地址(参见清单 9–12)。此外,在网上提交表单时,建议先发布,然后重定向,以避免任何重复提交的问题。 -
Alternatively, you may manually set the
data-url
attribute on the page container. The value of thedata-url
attribute will be shown in the browser's location bar. This also gives developers more flexibility when constructing semantic paths:data-url="/manually/set/url/path/”
这种策略也可以用来隐藏文件名。例如,如果您转到“
/my/movies/index.html
”,您可以将页面的data-url
属性更新为”/my/movies/”
,这将隐藏 index.html 部分,使其不显示。
使用 MVC 的服务器端数据访问
在前面的例子中,我们看到了如何将表单数据发送到服务器。在这个例子中,我们将使用 GET 请求从服务器获取数据。这个例子将从服务器获取电影列表,并在 jQuery Mobile JSP 页面中显示结果(参见 Figure 9–7)。
图 9–7。 从服务器端 MVC 访问中获取的电影
在服务器端,我们有一个 Spring MVC 控制器设置来处理以下 href 上的 GET 请求:
<a href="**/jqm-webapp/mvc/movies**" data-role=”button”>Movies</a>
当按钮被点击时,一个 GET 请求将被触发并发送给我们的 MoviesController。MoviesController 将检索我们的电影数据,并将响应转发给电影 JSP 页面(参见清单 9–15)。
清单 9–15。【com.bmb.jqm.MoviesController.java】MVC 控制器获取电影数据
`@Controller()
public class MoviesController {
** @RequestMapping(method = RequestMethod.GET)**
public String getMovies(ModelMap model) {
model.addAttribute("movies", getMovieData());
return "movies";
}
}`
响应将被转发到电影页面,JSP 将迭代电影列表,为每个结果显示一个单独的列表项(参见清单 9–16)。
清单 9–16。 JSP 显示电影数据(/jsp/movies.jsp)
`
** <c:forEach var="movie" items="\({movies}">** <li> <a href="#"> <img src="img/**\){movie.image}" />
\({movie.title}**</h3>
<p>Rated: **\){movie.rating}
Runtime: ${movie.runtime} min.
** </c:forEach>
这种服务器端解决方案的一个优点是页面标记的简单性。没有 JavaScript 的动态页面生成、字符串连接或 jQuery 选择器的动态字段绑定,我们在前面的客户端示例中已经看到了。
服务器端与客户端
决定实施哪种服务访问策略取决于几个因素。如果您现在已经在构建 Web 应用,那么您可能已经有了一个在 Web 上访问数据的既定模式。如果是这样,出于一致性目的,您可能希望继续使用这种策略。幸运的是,当正确实现时,jQuery Mobile 将与这两种策略很好地集成,最终您可以共同选择最适合您特定应用需求的模式。以下是每种策略的支持性注意事项:
客户端集成:
-
Faster response times. Client-side integrations produce faster response times because they have fewer point-to-point server dependencies. For instance, we could have aggregated our Twitter data on the server-side but our response times would have decreased due to the additional server communication.
注意:虽然客户端集成提供了更快的响应时间,但在与第三方 API 集成时要小心,因为在服务器端封装它们有利于更好地将您自己的页面与第三方修改隔离开来。例如,脸书的 RESTful API 在过去经常改变,现在它实际上被否决了。
-
更快地实现。我们在客户端的 Twitter 例子是一个非常快速的实现,因为只有我们的客户端标记需要修改。在服务器端实现这项任务需要修改客户端和服务器端组件。
服务器端集成:
- 比较靠谱。服务器端解决方案比客户端解决方案更可靠,因为您不必担心客户端 JavaScript 的不兼容性。
- 更安全。当实现客户端解决方案时,您必须小心暴露的 API 和数据类型。如果您正在与暴露个人身份信息(PII)、个人健康信息(PHI)或支付卡行业(PCI)信息的 API 集成,客户端解决方案将是不可取的。
- 更清晰的页面标记。在比较使用服务器端和客户端访问策略实现的页面时,我们看到了这样的例子。我们的服务器端访问示例中使用的页面不依赖于定制的 JavaScript。
- 更简单的组件单元测试。我相信服务器端单元测试仍然比客户端单元测试简单。然而,在对 jQuery Mobile 项目进行了几次 QUnit 测试之后,我开始相信客户端单元测试可以非常成功和可靠!
谷歌地图整合
在最近的一项移动 Web 调查中,近 75%的 Web 开发人员使用地理定位,使其成为最受欢迎的 HTML5 API。 13 在构建位置感知应用时,通常会有一个显示兴趣点或方向的地图视图。在网络上,地理定位 14 结合谷歌地图 15 为构建地图功能提供了非常有用的 API。在这一节中,我们将了解 jQuery Mobile 与地理定位和谷歌地图的集成情况。首先,我们将创建一个示例,在地图上标出您的当前位置(参见图 9–8)。
13 见www . webdirections . org/somw 2011/
。
14 见【http://dev.w3.org/geo/api/spec-source.html】的。
15 见code . Google . com/APIs/maps/documentation/JavaScript/basics . html
。
图 9–8。 谷歌地图与 jQuery Mobile 整合
页面中的标记很少,因为我们只需要为地图创建内容容器(参见清单 9–17)。
清单 9–17。 用于谷歌地图集成的 jQuery Mobile 页面标记(ch9/maps.html)
`
Maps
<div data-role="content" id="map-canvas">
当与谷歌地图集成时,有几个附加功能是必需的:
- 首先,我们需要设置页面和地图容器的样式,使其全屏显示:
**#map-page, #map-canvas { width: 100%; height: 100%; padding: 0; }**
- 接下来,我们导入定制的 JavaScript 来帮助确定用户的地理位置并绘制地图视图。我们很快就会看到这个文件的细节:
**<script type="text/javascript" src="maps.js"></script>**
- 然后,我们导入 Google Maps API:
**<script src="http://maps.google.com/maps/api/jssensor=false">**
- 最后,我们确定我们的地图容器。我们的地图将在这个元素内绘制:
<div data-role="content" **id="map-canvas"**>
帮助确定用户地理位置和绘制地图视图的定制 JavaScript 如清单 9–18 所示。
清单 9–18。 用于谷歌地图集成的 JavaScript(ch9/Maps . js)
`$( "#map-page" ).live( "pageinit", function() {
* // Default to Hollywood, CA when no geolocation support*
var defaultLatLng = new google.maps.LatLng(34.0983425, -118.3267434);
if ( navigator.geolocation ) {
function success(pos) {
* // Location found, show coordinates on map*
drawMap(new google.maps.LatLng(
pos.coords.latitude, pos.coords.longitude));
}
function fail() {
drawMap(defaultLatLng); // Show default map
}
* // Find users current position*
** navigator.geolocation.getCurrentPosition**(success, fail,
{enableHighAccuracy:true, timeout: 6000, maximumAge: 500000});
} else {
drawMap(defaultLatLng); // No geolocation support
}
function drawMap(latlng) {
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map-canvas"), myOptions);
* // Add an overlay to the map of current lat/lng*
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: "Greetings!"
});
}
});`
当地图页面处于“就绪”状态时,我们将执行以下步骤来绘制地图视图:
-
首先,我们确定浏览器是否支持地理定位:
if ( **navigator.geolocation** ) {
-
If the browser supports Geolocation we will attempt to retrieve the users current position:
navigator.geolocation.getCurrentPosition(success, fail,
{ enablehigaccuracy:true,timeout: 6000,maximumAge:500000 });
getCurrentPosition
API 最多可以接受三个参数。第一个参数是成功回调。这是唯一必需的参数。下一个参数是错误回调,最后一个参数是我们的可配置选项。我们已经将地理位置查找配置为使用高精度。如果支持,这将尝试使用 GPS 定位。我们还将超时设置为 6 秒。如果我们在 6 秒后没有找到用户的位置,我们的错误回调将被调用。最后,我们已经配置了查找可以使用缓存的位置,如果它不到 5 分钟。 -
当找到一个成功的位置时,将调用成功回调。在这种情况下,我们将使用位置坐标:
function **success**(pos) { **drawMap**(new google.maps.LatLng( pos.coords.latitude, pos.coords.longitude)) }
来绘制地图 -
最后,
drawMap
方法将绘制一张 Google 地图,在地图中心被标识为您所在位置的位置显示一个覆盖图标。但是,如果不支持地理定位或者没有建立位置,加利福尼亚州好莱坞将显示为默认位置(参见清单 9–18)。
总结
在本章中,我们看到了如何将 jQuery Mobile 与客户端和服务器端的数据访问策略相集成。jQuery Mobile 很好地集成了这两种策略,允许您选择最适合您的应用需求的访问方法。虽然客户端策略提供了更好的性能,并且可以更快地实现,但它可能不如服务器端策略可靠、安全或可维护。
最后,我们看到了一个如何将 jQuery Mobile 与地理定位和 Google Maps 集成的例子。有了这两个 mapping API,我们现在能够将地图视图添加到 jQuery Mobile 应用中。
在第十章中,我们将看看如何利用现有的 jQuery Mobile 应用,并通过 PhoneGap 在本地发布它们。
十、使用 PhoneGap 轻松部署
与移动网络应用相比,本地应用似乎有两个明显的优势。首先,原生应用可以在应用商店中分发。最著名的应用商店包括苹果应用商店、安卓市场、惠普应用目录、黑莓应用世界和 Windows 市场。当消费者需要搜索、购买、安装或评价原生应用时,应用商店简化了用户体验。本机应用的另一个优势是它们能够与设备 API 进行交互。例如,本地应用能够与大多数设备 API 进行通信,包括联系人、日历、相机和网络 API 等。
在这一章中,我们将讨论如何打破这些移动网络壁垒。特别是,我们将介绍 PhoneGap,并展示 PhoneGap 如何帮助我们的 jQuery Mobile 应用弥合这些差距。例如,我们将使用一个现有的 jQuery Mobile 应用,用 PhoneGap 包装它,并将我们的应用部署到原生 iOS 和 Android 平台。
我们还将看到如何在没有 PhoneGap 的情况下将我们的 jQuery Mobile 应用分发到应用商店。例如,Open App Market 是一个 HTML5 移动应用的应用商店,对于那些发现原生应用商店分发过程繁琐而缓慢的人来说,它可以是一个替代选择。
最后,我们将看一看 W3C 在客户端设备 API 上取得的进展,将来有一天浏览器会支持这些 API。这对于移动网络来说非常重要,因为它将允许我们的网络应用访问设备 API(日历、联系人、照相机等)。)对外部框架的依赖性为零。
什么是 PhoneGap?
PhoneGap 1 例如,我们可以使用现有的 jQuery Mobile web 应用,用 PhoneGap 框架包装它,并将其分发给 PhoneGap 支持的所有本机平台。目前,PhoneGap 支持原生 iOS、Android、BlackBerry、webOS 和 Symbian 平台。除了 PhoneGap 的原生分发功能,它还公开了一个 API,允许我们的移动 Web 应用与特定于设备的 API 进行交互,包括文件系统、通知和摄像头等等。有关完整列表,请参考 PhoneGap 平台支持的功能。2PhoneGap API 允许我们以以前只有原生 SDK 才有可能的方式扩展我们的 jQuery Mobile 应用。
将 jQuery Mobile 作为 iOS 应用运行
在本节中,我们将使用 PhoneGap 包装一个 jQuery Mobile 应用,并在原生 iOS 平台上运行它。要为 iOS 平台设置 PhoneGap,我们可以参考 PhoneGap 的《iOS 入门指南》。PhoneGap 有在每个平台上安装 PhoneGap 的分步说明,它们的说明非常详细,并有截图作为辅助。安装 Xcode,iOS 开发的 IDE?? 4T7,是开发到 iOS 平台的前提。如果您选择绕过 Xcode 安装,那么继续学习以熟悉在本机平台上设置 PhoneGap 所必需的一般步骤仍然是有价值的。虽然每个平台都有特定的 IDE 设置说明,但是安装 PhoneGap、设置项目和部署的一般过程对于所有平台都是一致的。设置好 iOS 平台后,您应该有一个新的 Xcode 项目,看起来类似于 Figure 10–1。
1 见[
www.phonegap.com/.](http://www.phonegap.com)
2 参见[
www.phonegap.com/about/features](http://www.phonegap.com/about/features).
3 见[
www.phonegap.com/start#ios-x4](http://www.phonegap.com/start#ios-x4).
4 见[
developer.apple.com/xcode/.](http://developer.apple.com/xcode)
图 10–1。 支持 PhoneGap 的初始 Xcode 项目
图 10–1 所示的“www”目录是应用根目录。在这个目录中有 PhoneGap JavaScript 库和一个默认页面(index.html)。当我们运行应用时,index.html 页面将显示为初始登录页面。在 Xcode 中,要构建和运行应用,请点按出现在 Xcode 左上角的“运行”按钮。点击“运行”后,应用将编译,iOS 模拟器将启动,并显示索引页面(参见图 10–2)。
图 10–2。 在 Xcode 中运行 PhoneGap 默认应用时的初始屏幕
通过在 Xcode 中设置 PhoneGap 项目,我们现在可以将现有的 jQuery Mobile 应用导入到我们的项目中。下面列出了将 jQuery Mobile 应用导入 Xcode 项目并部署为原生 iOS 应用的步骤:
-
First, we need to import an existing jQuery Mobile project into Xcode's “www” root directory. For this exercise, you may import your own jQuery Mobile app or import the jQuery Mobile project that is included in the chapter 10 source code folder. For example, if we import the jQuery Mobile files from the Chapter 10 source code directory and move them into our “www” directory, our Xcode project structure should appear as the figure below:
-
After importing the jQuery Mobile project into our PhoneGap project we need to import PhoneGap's JavaScript library as a top-level resource: `
jMovies
** **
`PhoneGap 库是一个 API,它提供了对许多设备特定功能(相机、媒体、存储等)的访问。).PhoneGap 在其网站 5 上提供了所有支持的 API 的文档和示例。只有当您的应用需要与 PhoneGap 的本机功能进行交互时,才需要导入 PhoneGap 库。
-
最后一步是运行和测试应用。在 Xcode 中,点按“运行”按钮。这将编译应用,并在 iOS 模拟器中启动它。如果您从第十章源代码中导入了 jQuery Mobile 项目,那么最初出现的屏幕将是跳板(参见图 10–3)。
5 见[
docs.phonegap.com/](http://docs.phonegap.com).
图 10–3。 jQuery Mobile 作为原生 iOS app 运行
为了帮助验证 PhoneGap 库是否正确安装,我为 PhoneGap 的device-ready
事件添加了一个监听器。当该事件触发时,PhoneGap 处于就绪状态,我们可以开始与 PhoneGap API 通信(参见清单 10–1)。
清单 10–1。 PhoneGap 准备好了(ch10/custom.js
)
$(document).bind("**deviceready**", function(){ ** navigator.notification.alert("PhoneGap is initialized...");** });
如 Figure 10–3 所示,当 PhoneGap 处于就绪状态时,我们会显示一个警告视图,指示 PhoneGap 已经初始化。清单 10–1 中的警报通知是一个例子,展示了我们如何通过编程与 PhoneGap 的 API 进行交互来访问本地功能。
注: PhoneGap 已经简化了将我们的 jQuery Mobile web 应用转换到运行在 iOS 上的原生平台的过程。从技术角度来看,我们的 jQuery Mobile web 应用现在运行在 iOS Web 视图中。
当比较我们在 Safari 浏览器中运行的 jQuery Mobile 应用(参见图 10–4)和在 iOS 中运行的本地应用(参见图 10–5)时,您发现有什么不同吗?
图 10–4。 jQuery 手机浏览器内运行
图 10–5。 jQuery Mobile 作为原生 iOS 应用运行
最明显的区别是浏览器 chrome 在 Safari 浏览器中可用,但在原生应用中不可用。如果你还记得我们在第三章的“后退按钮”部分,后退按钮最初在 jQuery Mobile 中是禁用的,因为浏览器 chrome 已经提供了内置的导航按钮。然而,对于运行原生 iOS 应用的用户来说,标题中的后退按钮是主要的导航方式。幸运的是,我们可以通过简单的配置更新在 jQuery Mobile 中启用后退按钮(参见清单 10–2)。
清单 10–2。 全局启用后退按钮(ch10/custom.js
)
$(document).bind("mobileinit", function(){ ** $.mobile.page.prototype.options.addBackBtn = true;** });
jQuery Mobile 中的后退按钮非常智能。只有当历史中有一页可以返回时,它才会出现。在全球启用后退按钮后,我们的原生 iOS 用户在导航应用时会感到更加舒适(参见 Figure 10–6)。
图 10–6。 全局启用后退按钮进行导航支持
在全局启用后退按钮的情况下,我们可能还想在不需要它们的特定页面上禁用它们。特别是,我们将希望防止返回按钮出现在主屏幕上。为了防止后退按钮出现在给定的页面上,我们可以向页面容器添加data-add-back-btn=”false”
属性:
<div data-role="page" id="home" **data-add-back-btn="false"**>
因此,当我们导航回主屏幕时,将不会显示后退按钮。
既然我们已经能够将 jQuery Mobile 应用部署到原生 iOS 平台,我们还需要定制默认应用图标(参见图 10–7)和闪屏(参见图 10–8)。
图 10–7。 PhoneGap 在 iOS 中的默认应用图标
图 10–8。 PhoneGap 在 iOS 中的默认闪屏
应用图标存储在项目的/Resources/icons 目录中,闪屏图像存储在/Resources/splash 目录中(参见 Figure 10–9)。图像适用于不同的 iOS 屏幕密度和尺寸。
图 10–9。 Xcode 的闪屏图像和应用图标
此外,当您需要更改包显示名称或标识符时,可以在项目的“信息”标签中的 Xcode 中进行设置(参见图 10–10)。捆绑包显示名称设置应用图标的标签,iOS 使用捆绑包标识符来唯一标识您的应用。
图 10–10。 设置捆绑显示名称和标识符
提示:使用 PhoneGap 开发时,建议将$.mobile.allowCrossDomainPages
配置选项设置为true
:
$(document).bind(“mobileinit”, function(){ ** $.mobile.allowCrossDomainPages = true;** });
Phone Gap 的 web 视图允许应用进行跨域呼叫。这通常是允许的,这样应用可以从他们的主服务器获取数据。默认情况下,jQuery Mobile 会将跨域请求视为外部链接。因此,跨域页面不会加载到当前页面的 DOM 中,也不会应用任何过渡。因此,如果你想让 jQuery Mobile 管理 PhoneGap 中跨域请求的页面加载逻辑,就把这个选项设置为true
。
这就完成了从安装 PhoneGap 到在原生 iOS 平台上运行我们的 jQuery Mobile 应用的整个过程。在你的应用准备好生产后,最后一步是将你的 iOS 应用分发到苹果的应用商店。虽然这个过程可能会很漫长,但在苹果的 iOS 开发者库 6 中可以找到将你的应用分发到苹果应用商店的完整说明。
将 jQuery Mobile 作为 Android 应用运行
在本节中,我们将使用 PhoneGap 包装一个 jQuery Mobile 应用,并在原生 Android 平台上运行它。在 Android 平台上设置 PhoneGap,我们会参考 PhoneGap 的《Android 入门指南》 7 。安装 Eclipse,Android 开发的 IDE,是一个先决条件。在你的 Android 平台建立之后,你应该有一个类似于图 10–11 的新 Eclipse 项目。
⑥见[
developer.apple.com/library/ios/#documentation/Xcode/Conceptual/ios_development_workflow/145-Distributing_Applications/distributing_applications.html](http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/ios_development_workflow/145-Distributing_Applications/distributing_applications.html).
7 见[
www.phonegap.com/start#android](http://www.phonegap.com/start#android).
图 10–11。 支持 PhoneGap 的初始 Eclipse 项目
图 10–11 所示的“www”目录是应用根目录。在这个目录中有 PhoneGap JavaScript 库和一个默认页面(index.html)。当我们运行应用时,index.html 页面将显示为初始登录页面。在 Eclipse 中,要构建和运行应用,单击 run 菜单,选择 Run As,然后选择 Android Application。在我们编译并运行应用后,Android 模拟器将会启动并显示索引页面(参见图 10–12)。
图 10–12。Eclipse 中运行 PhoneGap 默认应用时的初始屏幕
提示:如果您发现 Android 模拟器启动时间太长,您可能更愿意部署到实际设备上进行测试。对于这个设置,确保 USB 调试在你的设备上启用(设置应用开发)并将其插入你的系统。现在,当您运行您的应用时,它会启动得更快。
有了 Eclipse 中的 PhoneGap 项目设置,我们现在可以将现有的 jQuery Mobile 应用导入到我们的项目中。下面列出了将 jQuery Mobile 应用导入 Eclipse 项目并作为原生 Android 应用进行部署的步骤:
-
First, we need to import an existing jQuery Mobile project into Eclipse's “www” root directory. For this exercise, you may import your own jQuery Mobile app or import the jQuery Mobile project that is included in the chapter 10 source code folder. For example, if we import the jQuery Mobile files from the Chapter 10 source code directory and move them into our “www” directory, our Eclipse project structure should appear as shown in Figure 10–13:
图 10–13。 一个日食项目
-
将 jQuery Mobile 项目导入 Eclipse 项目后,我们需要导入 PhoneGap 的 JavaScript 库作为顶层资源:
`<head> <meta charset="utf-8"> <title>jMovies</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="jquery.mobile-min.css" /> <link rel="stylesheet" type="text/css" href="custom.css" /> ** <script type="text/javascript" src="phonegap-1.0.0.js"></script>** <script type="text/javascript" src="jquery-min.js"></script>
`
-
最后一步是运行和测试应用。在 Eclipse 中,单击运行菜单,选择运行方式,然后选择 Android 应用。这将编译应用,并在 Android 模拟器中启动它。如果您从第十章源代码中导入了 jQuery Mobile 项目,那么最初出现的屏幕将是跳板(参见图 10–14)。
图 10–14。 从 Eclipse 运行 PhoneGap 时的初始屏幕
如果你还记得我们的 iOS 示例,我们在所有屏幕上都全局启用了后退按钮,因为后退按钮通常固定在 iOS 应用的标题中。由于 Android 有一个基于硬件的后退按钮,所以没有必要启用我们的后退按钮(参见图 10–15)。
图 10–15。 安卓系统不需要后退按钮
提示:在单独的文件中提取特定于平台的依赖关系。这种分离将有助于简化跨平台的不同配置的管理。例如,为每个支持的平台创建一个单独的配置文件:custom-ios.js,custom-android.js。
既然我们已经能够将我们的 jQuery Mobile 应用部署到原生 Android 平台,我们还需要定制默认的应用图标(参见图 10–16)。
图 10–16。Android 中 PhoneGap 的默认应用图标
Android 应用图标存储在项目的/res/drawable-*目录中,图像可用于高、中、低密度(参见图 10–17)。
图 10–17。 安卓的应用图标图片
这就完成了从安装 PhoneGap 到在原生 Android 平台上运行我们的 jQuery Mobile 应用的整个过程。当你的应用准备生产时,最后一步是将你的 Android 应用发布到 Android Market。将你的应用发布到 Android Market 的完整说明可以在 Android 的开发指南中找到。 8
开放应用市场
开放应用市场 9 是一个 HTML5 移动应用的应用商店,允许我们像本地应用商店一样搜索、购买、安装或评价 HTML5 移动应用(参见图 10–18)。
8 见[
developer.android.com/guide/publishing/publishing.html](http://developer.android.com/guide/publishing/publishing.html).
9 见[
openappmkt.com/](http://openappmkt.com).
图 10–18。 开放 App 市场
要开始使用 Open App Market,我们必须首先将它安装到我们的设备上。目前,开放的应用市场对 iOS 和 Android 用户开放。要安装 Open App Market,请使用您的 iOS 或 Android 设备扫描图 10–19 中的二维码。
图 10–19:二维码安装打开 App 市场。或者,你可以去 openappmkt.com,点击他们网站顶部的安装链接。
安装应用后,您可以按类别或受欢迎程度搜索移动网络应用。当你发现一个你感兴趣的免费或付费应用时,下载它,该应用将被保存在你的主屏幕上,就像来自原生应用商店的应用一样。例如,图 10–20 显示了开放应用市场应用以及从开放应用市场下载的 Twitter 和 YouTube 应用。
图 10–20。 开放应用市场下载应用的方式与本地商店相同
客户端设备 API
如果你需要建立一个移动应用,它必须集成设备特定的功能,如相机、联系人或网络,你会选择什么移动技术?今天,我们的选择有限。我们必须要么使用本地平台,要么使用 PhoneGap 这样的混合技术。如果所有的网络浏览器都支持这些特定于设备的特性,那就太理想了。虽然目前没有浏览器支持这些特性,但是 W3C 目前正在为大多数主要的客户端设备 API10实现工作草案。最值得注意的客户端设备 API 包括对相机、网络、日历、联系人、消息和电池信息的访问。虽然现在预测浏览器何时支持这些功能还为时过早,但至少进展已经很顺利了。
10 见[
www.w3.org/2009/dap/.](http://www.w3.org/2009/dap)
总结
在本章中,我们看到了如何使用现有的 jQuery Mobile 应用,并将其与 PhoneGap 框架集成。PhoneGap 为 jQuery Mobile web 应用添加了两个独特的功能。首先,我们可以将现有的 jQuery Mobile web 应用封装在 PhoneGap 框架中,并将其分发到原生的 iOS、Android、BlackBerry、WebOS 和 Symbian 平台。其次,PhoneGap 还公开了一个 API,允许我们的移动 Web 应用与特定于设备的 API 进行交互,包括文件系统、通知、摄像头等等。PhoneGap API 允许我们扩展我们的 jQuery Mobile 应用,这在以前只能通过本地 SDK 来实现。
我们还推出了 Open App Market,这是一个面向 HTML5 移动应用的应用商店,允许我们像本地应用商店一样搜索、购买、安装或评价 HTML5 移动应用。对于那些发现本地应用商店分发过程繁琐而缓慢的人来说,开放的应用市场可以是一个替代选择。
最后,我们介绍了 W3C 目前正在开发的客户端设备 API。这些 API 对于移动网络开发者来说非常重要,因为它将允许我们的网络应用访问设备 API(日历、联系人、照相机等)。)对外部框架的依赖性为零。