使用Sencha Touch開(kāi)發(fā)移動(dòng)Web應(yīng)用平臺(tái)
Sencha Touch 是由 Sencha 公司開(kāi)發(fā)的移動(dòng) Web 應(yīng)用開(kāi)發(fā)框架,用以提升主流移動(dòng)設(shè)備在瀏覽器上的觸碰操作,增強(qiáng)用戶體驗(yàn)。該框架以久負(fù)盛名的 Ext JS 富客戶端框架為基礎(chǔ),并支持最新的 HTML5 及 CSS3 標(biāo)準(zhǔn),與流行的 Apple iOS 和 Andriod 設(shè)備兼容。一方面,它以 Webkit 瀏覽器引擎為基礎(chǔ),提供了出色的性能和用戶體驗(yàn);另一方面,它提供了基于 GPL V3 許可的開(kāi)源版本和詳盡的 API 文檔,體現(xiàn)了良好的開(kāi)放性和易用性。因此,該框架可幫助移動(dòng)應(yīng)用開(kāi)發(fā)人員提升開(kāi)發(fā)效率,從而創(chuàng)造出更多富有創(chuàng)意的移動(dòng)應(yīng)用。
隨著智能移動(dòng)設(shè)備的普及和 3G 通訊技術(shù)的發(fā)展,將會(huì)有越來(lái)越多的傳統(tǒng)應(yīng)用部署為移動(dòng) Web 應(yīng)用,而良好兼容性和操控性是 Web 應(yīng)用成功的關(guān)鍵。本文將分為以下四個(gè)部分介紹 Sencha Touch 的獨(dú)特之處,并結(jié)合示例為相關(guān)移動(dòng)應(yīng)用的開(kāi)發(fā)人員編寫(xiě)良好兼容性和操控性的 Web 程序提供借鑒。
與眾不同的 Sencha Touch:功能和特性
Sencha Touch 是世界上第一個(gè)支持 HTML5 和 CSS3 標(biāo)準(zhǔn)的移動(dòng)應(yīng)用框架,你可以使用 HTML5 來(lái)編寫(xiě)音頻和視頻組件,還可以使用 LocalStorage Proxy 來(lái)存儲(chǔ)離線數(shù)據(jù),同時(shí),大量 CSS3 樣式表為你提供了創(chuàng)建健壯樣式層的可能。該框架在提供豐富功能的基礎(chǔ)上對(duì) JavaScript 庫(kù)文件進(jìn)行合理優(yōu)化,使得經(jīng)過(guò) gzipped 壓縮后的庫(kù)文件在 120kb 以下,最大限度地提升了 Web 應(yīng)用在瀏覽器中的加載速度,增強(qiáng)了用戶體驗(yàn)。
除了對(duì)最新標(biāo)準(zhǔn)的支持,該框架最大的特色正如其名,增強(qiáng)了對(duì)手持移動(dòng)設(shè)備觸控操作的支持,除了支持瀏覽器標(biāo)準(zhǔn)的觸摸事件,還額外添加了如 tap, double tap, swipe, tap-hold, pinch 和 rotate 等富有吸引力的操作事件,使用戶體驗(yàn)到與原生程序一樣的效果。
Sencha Touch 另一大優(yōu)勢(shì)在于其跨平臺(tái)性,由于 Apple iOS 和 Andriod 設(shè)備有其獨(dú)立的開(kāi)發(fā)、測(cè)試和運(yùn)行環(huán)境,針對(duì)某一平臺(tái)開(kāi)發(fā)的應(yīng)用在另一平臺(tái)是不兼容的,這大大增加了移動(dòng)應(yīng)用的開(kāi)發(fā)成本。而基于 Sencha Touch 開(kāi)發(fā)的 Web 應(yīng)用具有與原生應(yīng)用相同的用戶體驗(yàn),同時(shí)兼容 Apple iOS、Andriod 和黑莓 RIM 6 設(shè)備,可以滿足大部分的市場(chǎng)需求。
此外,借助 Ext JS 多年來(lái)對(duì) Ajax 數(shù)據(jù)集成的經(jīng)驗(yàn),該框架提供了豐富的數(shù)據(jù)處理功能。開(kāi)發(fā)人員能夠方便地處理各種格式的數(shù)據(jù)如 XML、JSON,并能靈活地綁定到可視化組件加以展示。
個(gè)性鮮明的 UI 組件
表單是用戶與應(yīng)用程序交互的基本媒介,如用戶信息注冊(cè)、應(yīng)用程序配置、個(gè)人評(píng)論的發(fā)表這些常見(jiàn)的 Web 應(yīng)用場(chǎng)景都需要表單組件的支持。Sencha Touch 為我們提供了形式多樣、操作簡(jiǎn)單的 表單組件 。圖 1 中第一個(gè)界面所展示的是基本表單元素,包括多種類型的輸入框,如純文本、密碼、郵件、URL 地址等類型,并能根據(jù)用戶輸入的文本進(jìn)行有效性驗(yàn)證,以減少開(kāi)發(fā)者對(duì)用戶輸入格式的驗(yàn)證代碼,同時(shí),基本表單還支持單選、多選、日歷選擇、多行文本輸入等控件類型。圖 1 第二個(gè)界面展示了觸控屏手持設(shè)備所特有的滑動(dòng)條組件,適合調(diào)整一些連續(xù)性的數(shù)值和作為切換的開(kāi)關(guān)按鈕。圖 1 中第三個(gè)界面展示了建立在工具條上的表單控件,非常適用于搜索和文本過(guò)濾的應(yīng)用場(chǎng)景。
圖 1 表單組件
列表是移動(dòng) Web 應(yīng)用展示信息最為常見(jiàn)的組件,其中比較有特色的是分組列表(Grouped List)(如 圖 2 中第一個(gè)界面),它可以根據(jù)所列項(xiàng)目的首字母進(jìn)行排序分組,當(dāng)用戶觸摸屏幕右側(cè)字母索引時(shí),屏幕可快速滾動(dòng)并定位至對(duì)應(yīng)分組,非常適合于列表信息較多的情況,如聯(lián)系人列表,歌曲列表等。圖 2 中第二個(gè)界面所示的嵌套列表(Nested List)則非常適合于展示信息有層級(jí)關(guān)系的情況,如瀏覽論壇時(shí)的“討論區(qū) -> 主題帖 -> 原帖及回復(fù)內(nèi)容”這樣的層次關(guān)系。
圖 2 列表組件
精致形象的圖標(biāo)和布置合理的工具欄是 Apple iOS 原生應(yīng)用引以為傲的部分,而 Sencha Touch 也可以做到這一點(diǎn)。圖 3 中第一個(gè)界面所示的是框架內(nèi)置的圖標(biāo)樣式,已可以滿足大部分應(yīng)用的需要,開(kāi)發(fā)人員還可以通過(guò)自定義圖標(biāo)樣式來(lái)擴(kuò)展出更多更豐富的圖標(biāo)。如 圖 3 中第二個(gè)界面所示,圖標(biāo)所在的工具欄布置方式也靈活多樣,即可在屏幕頂部或者底部,也可以多個(gè)層疊,并可以在工具欄上布置形狀各異的按鈕。圖 3 中第三個(gè)界面所展示的是根據(jù)底部 Tab 標(biāo)簽頁(yè)而進(jìn)行切換的面板,不同的面板中可以包含不同的主題內(nèi)容。
圖 3 圖標(biāo)、工具欄和標(biāo)簽頁(yè)
如果你以為 Sencha Touch 只能做到以上這些小兒科,那就錯(cuò)了,下面展示了一些高級(jí)的 UI 功能。圖 4 中第一個(gè)界面類似于 Apple iOS 設(shè)備上的 SpringBoard 操作,可以通過(guò)手指的左右或者上下滑動(dòng),來(lái)旋轉(zhuǎn)切換界面窗口;圖 4 中第二個(gè)界面顯示了一個(gè)窗口重疊的效果,當(dāng)上層彈出窗口激活時(shí),下層窗口的操作是被屏蔽的,在提醒用戶執(zhí)行一些重要操作的場(chǎng)景中(如刪除或者保存),這樣的 UI 組件是非常好用的。
圖 4 旋轉(zhuǎn)切換與窗口的重疊效果
酷炫的動(dòng)畫(huà)效果
一直以來(lái),基于瀏覽器的 Web 程序動(dòng)畫(huà)效果常被人詬病,尤其是基于 JavaScript 的動(dòng)畫(huà)效果庫(kù)相對(duì)于原生的應(yīng)用程序來(lái)說(shuō),還是存在一定的差距,而剛發(fā)布的 Sencha Touch 1.1.0 版本就支持多達(dá)六種動(dòng)畫(huà)效果,分別是 cube、fade、flip、pop、slide 和 wipe。以最為酷炫的 3D 旋轉(zhuǎn) Cube 動(dòng)畫(huà) 為例,它將當(dāng)前顯示的界面面板(稱之為 Card)想象為立方體的一個(gè)面,而即將展示的 Card 作為相鄰的另外一個(gè)面,以左上方的頂點(diǎn)作為旋轉(zhuǎn)基點(diǎn)進(jìn)行旋轉(zhuǎn),從而得到 Card 之間切換的動(dòng)畫(huà)效果。大家一定很好奇它是如何做到這一點(diǎn)的,我們通過(guò)查看該動(dòng)畫(huà)效果的源代碼即可找到答案。
圖 5 Cube 動(dòng)畫(huà)效果示例
在文件 sencha-touch-1.1.0\src\core\Anim.more.js 中,可以看到以下代碼片段
清單 1
- this.from = {
- '-webkit-transform': 'rotate' + rotateProp + '(' + fromRotate + 'deg)' +
- (showTranslateZ ? ' translateZ(' + fromZ + 'px)': '') + fromTranslate,
- '-webkit-transform-origin': origin
- };
- this.to = {
- '-webkit-transform': 'rotate' + rotateProp + '(' + toRotate + 'deg)
- translateZ(' + toZ + 'px)' + toTranslate,
- '-webkit-transform-origin': origin
- };
由于 Sencha Touch 的動(dòng)畫(huà)組件是基于 Webkit 核心的瀏覽器,所以其動(dòng)畫(huà)效果實(shí)際上是基于 Webkit 的 3D 轉(zhuǎn)換引擎,代碼中 this.from 指的是當(dāng)前 Card 如何旋轉(zhuǎn)消失的屬性,而 this.to 指的是要目標(biāo)的 Card 如何旋轉(zhuǎn)得以呈現(xiàn),具體 CSS 屬性的含義可參考 官方文檔 。
基于 Web 的博客瀏覽示例:應(yīng)用開(kāi)發(fā)環(huán)境的搭建、代碼結(jié)構(gòu)及測(cè)試
隨時(shí)隨地獲取自己想要關(guān)注的信息是移動(dòng)計(jì)算環(huán)境最直接的用途。本文將以一個(gè)簡(jiǎn)單的博客訂閱與瀏覽程序?yàn)槔?,展示基?Sencha Touch 進(jìn)行移動(dòng) Web 應(yīng)用開(kāi)發(fā)的流程,幫助開(kāi)發(fā)人員更快的熟悉該編程框架。博客訂閱與瀏覽應(yīng)用的主要功能是訂閱自己關(guān)注的博客 RSS 源,瀏覽對(duì)應(yīng)博客的主題列表,查看博文內(nèi)容。為了實(shí)現(xiàn)以上需求,開(kāi)發(fā)人員需要完成以下幾個(gè)步驟的工作。
#p#
搭建開(kāi)發(fā)環(huán)境
第一,下載 Sencha Touch 庫(kù)文件 ,并將其解壓到本地目錄 %sencha-touch-home%;第二,進(jìn)入 Eclipse Java EE IDE,創(chuàng)建一個(gè)名為 myblog 動(dòng)態(tài) Web 工程;第三,在本地安裝 Apache Tomcat 6.0.x ,在 eclipse 中將其配置為 Web server 并將 myblog 工程部署其中以備測(cè)試;第四,安裝 Andriod Virtul Machine 環(huán)境,用以啟動(dòng)一個(gè)虛擬設(shè)備來(lái)測(cè)試 Web 應(yīng)用的效果。需要說(shuō)明的是,對(duì)于靜態(tài)的 Sencha Touch 工程,Tomcat 并不是必須的,可使用任意 HTTP Server 來(lái)部署應(yīng)用,但由于本例中使用了 Servlet 解析 RSS 源來(lái)降低客戶端負(fù)載,因此采用了 Servlet 容器 Tomcat。
創(chuàng)建代碼結(jié)構(gòu)
一個(gè)典型的 Sencha Touch 工程主要由幾個(gè)部分組成:sencha-touch 庫(kù)文件,JavaScript 文件,CSS 文件,圖標(biāo)文件以及靜態(tài) HTML 文件。sencha-touch 庫(kù)文件至少要包含默認(rèn)的 CSS 文件 sencha-touch.css 和默認(rèn)的 JavaScript 文件 sencha-touch.js,值得一提的是,為了便于在開(kāi)發(fā)調(diào)試階段更準(zhǔn)確地定位和解決問(wèn)題,開(kāi)發(fā)包中還包含了 CSS 和 JavaScript 對(duì)應(yīng)的 debug 版本,開(kāi)發(fā)人員可在開(kāi)發(fā)階段使用該版本,而在產(chǎn)品部署階段再替換為對(duì)應(yīng)的正式版。
圖 6 工程目錄結(jié)構(gòu)
創(chuàng)建 HTML 和 JavaScript 文件
創(chuàng)建 Sencha Touch 應(yīng)用的第一步就是創(chuàng)建一個(gè) HTML 首頁(yè)文件用于鏈接 Sencha Touch 庫(kù)的 CSS 和 JavaScript 文件。我們博客瀏覽示例的 HTML 文件是 index.html,其內(nèi)容如下:
清單 2
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>My BLOG</title>
- <link rel="stylesheet" href="sencha-touch/resources/css/sencha-touch.css"
- type="text/css">
- <link rel="stylesheet" href="css/index.css" type="text/css">
- <script type="text/javascript" src="sencha-touch/sencha-touch-debug.js"></script>
- <script type="text/javascript" src="js/index.js"></script>
- </head>
- <body></body>
- </html>
當(dāng)創(chuàng)建好 HTML 文件之后,接下來(lái)就需要?jiǎng)?chuàng)建應(yīng)用程序的 JavaScript 文件 index.js,由于該示例是以瀏覽為主,因此選用 NestedList 組件作為 UI 界面的主體,相關(guān)代碼如下:
清單 3
- Ext.setup({
- icon : 'img/icon.png',
- tabletStartupScreen : 'img/tablet_startup.png',
- phoneStartupScreen : 'img/phone_startup.png',
- glossOnIcon : false,
- onReady : function() {
- .......
- var nestedList = new Ext.NestedList({
- fullscreen : true,
- title : '我的訂閱博客',
- displayField : 'text',
- dockedItems : [ topbar, bottombar ],
- store : store,
- getDetailCard : function(record, parentRecord) {
- return new Ext.ux.DescBox({
- value : 'Loading...',
- scroll : {
- direction : 'both',
- eventTarget : 'parent'
- }
- });
- }
- });
- ......
- });
- }
- });
可以看到,index.js 的第一行代碼調(diào)用了 Ext.setup() 方法,用以建立一個(gè)觸控設(shè)備的 Web 頁(yè)面,該方法可以為你的應(yīng)用設(shè)置不同的啟動(dòng)屬性和行為,例如示例代碼中的:
#p#
icon,設(shè)置該應(yīng)用默認(rèn)的圖標(biāo);
tabletStartupScreen,該屬性設(shè)置在平板電腦上的啟動(dòng)圖標(biāo);
phoneStartupScreen,該屬性設(shè)置在智能手機(jī)上的啟動(dòng)圖標(biāo);
glossOnIcon,該屬性設(shè)置是否在默認(rèn)圖標(biāo)上呈現(xiàn)光環(huán)效果;
onReady,該方法會(huì)在頁(yè)面加載完畢,瀏覽器中的 DOM 模型已經(jīng)建立完成時(shí)被調(diào)用。由于為了保證程序在運(yùn)行時(shí)所依賴的 JavaScript 文件都已經(jīng)加載完畢,我們一般將應(yīng)用啟動(dòng)的邏輯置于該方法內(nèi),類似于 Java 程序的 main 方法。
在定義 NestedList 組件時(shí),有四點(diǎn)值得我們注意:
界面布局:通過(guò) dockedItems 屬性,指明了 NestedList 頂部和底部分別放置了工具欄 topbar 和 bottombar,topbar 主要用來(lái)便于用戶登錄和設(shè)置偏好信息,bottombar 主要是用來(lái)提供瀏覽博客時(shí)的一些常用操作,如訂閱新的 RSS 源,刪除選擇的博客,刷新博客列表,給好的博文加星推薦以及回復(fù)功能。為了生成工具欄,需要生成一個(gè) Ext.Toolbar 對(duì)象的實(shí)例,以 bottombar 為例,其代碼如下:
清單 4
- var bottombar = new Ext.Toolbar({
- dock : 'bottom',
- defaults : {
- ui : 'plain',
- iconMask : true
- },
- scroll : 'horizontal',
- sortable : true,
- layout : {
- pack : 'center'
- },
- items : [ {
- iconCls : 'add',
- handler : function(btn, event) {
- addform.setCentered(true);
- addform.show();
- }
- }, {
- iconCls : 'trash'
- }, {
- iconCls : 'refresh'
- }, {
- iconCls : 'favorites'
- }, {
- iconCls : 'action'
- } ]
- });
該對(duì)象中主要定義了以下屬性:
dock,工具欄的放置位置,可選值有 top 和 bottom;
defaults,默認(rèn)圖標(biāo)的 UI 效果,其中 ui 指背景顏色的樣式,可選值有 dark,light 和 plain;
scroll,滾動(dòng)方向,可選值有 horizon,vertical 和 both;
layout,表示工具欄圖標(biāo)的布局方式,示例中表示的是居中排列。值得注意的是該屬性應(yīng)該由一個(gè) Object 對(duì)象來(lái)指定而不是 string;
items,該屬性用于指定一個(gè)數(shù)組,來(lái)表示工具欄中的圖標(biāo)元素的集合,每個(gè)圖標(biāo)對(duì)象至少需要有一個(gè) iconCls 屬性來(lái)指定其樣式,而 handler 屬性則用于指定處理圖標(biāo)點(diǎn)擊事件的方法,該方法回調(diào)時(shí)會(huì)傳入兩個(gè)參數(shù) function(btn, event),第一個(gè)指當(dāng)前被觸發(fā)事件的對(duì)象,第二個(gè)指被觸發(fā)的事件類型,本例中通過(guò)該方法彈出一個(gè)表單窗口用于提供給用戶輸入感興趣的博客 RSS 訂閱源。
圖 7 RSS 訂閱源添加表單
#p#
獲取數(shù)據(jù):從后臺(tái)通過(guò)相關(guān) API 獲取數(shù)據(jù)并展示在 UI 組件上,是實(shí)現(xiàn) Web 應(yīng)用的核心問(wèn)題,Sencha Touch 組件一般都是通過(guò)指定 store 數(shù)據(jù)源對(duì)象來(lái)實(shí)現(xiàn)的。例如在本例中,采用 Ext.data.TreeStore 對(duì)象來(lái)定義在 NestedList 中層次化數(shù)據(jù)的獲取,其相關(guān)代碼如下:
清單 5
- Ext.regModel('ListItem', {
- idProperty : 'text',
- fields : [ {
- name : 'text',
- type : 'string'
- }, {
- name : 'link',
- type : 'string'
- }, {
- name : 'description',
- type : 'string'
- } ]
- });
- var store = new Ext.data.TreeStore({
- model : 'ListItem',
- proxy : {
- type : 'ajax',
- url : '/myblog/list',
- reader : {
- type : 'tree',
- root : 'items'
- }
- }
- });
首先,通過(guò) model 屬性來(lái)指明返回?cái)?shù)據(jù)的模型,該模型是通過(guò) Ext.regModel() 方法來(lái)建立的,主要是為了告訴程序返回?cái)?shù)據(jù)是什么結(jié)構(gòu);其次,通過(guò) proxy 屬性來(lái)指明返回?cái)?shù)據(jù)的獲取方式,該框架中主要有兩種 Proxy,Client proxy 和 Server proxy,Client Proxy 主要用于存儲(chǔ)本地?cái)?shù)據(jù),其子類有三個(gè):
LocalStorageProxy,在瀏覽器支持的情況下將數(shù)據(jù)保存至 localStorage;
SessionStorageProxy,在瀏覽器支持的情況下將數(shù)據(jù)保存至 sessionStorage;
MemoryProxy,將數(shù)據(jù)保存在內(nèi)存中,但是當(dāng)頁(yè)面刷新時(shí),數(shù)據(jù)都將會(huì)丟失。
Server proxy 主要用于存儲(chǔ)一些通過(guò)遠(yuǎn)程請(qǐng)求服務(wù)器而獲取的數(shù)據(jù),它包括:
AjaxProxy,發(fā)送一個(gè) HTTP 請(qǐng)求到相同域的服務(wù)器;
ScriptTagProxy,使用 JSON-P 發(fā)送請(qǐng)求到不同域的服務(wù)器。
本例中采用的是最為常用的 Ajax 方式通過(guò)請(qǐng)求 servlet URL(/myblog/list) 來(lái)獲取 JSON 數(shù)據(jù)。
自定義組件:使用 NestedList 時(shí),開(kāi)發(fā)者要注意的是我們需要自己實(shí)現(xiàn) getDetailCard() 方法,用于定義對(duì)葉子節(jié)點(diǎn)數(shù)據(jù)的查看 UI 組件。非常幸運(yùn)的是,Sencha Touch 框架為我們提供了良好的擴(kuò)展機(jī)制用于自定義組件,這為我們構(gòu)建結(jié)構(gòu)清晰、面向?qū)ο蟮?JavaScript 程序打下了基礎(chǔ),示例中展示了如何擴(kuò)展出一個(gè)自定義組件,代碼片段如下:
清單 6
- ExtExt.ux.DescBox = Ext.extend(Ext.Component, {
- ...
- afterRender : function() {
- Ext.ux.DescBox.superclass.afterRender.apply(this, arguments);
- thisthis.description = this.getTargetEl().createChild({
- tag : 'pre',
- html : this.value
- });
- },
- getValue : function() {
- return this.value;
- },
- setValue : function(description) {
- this.value = description;
- if (this.rendered) {
- this.description.update(this.value);
- }
- }
- });
我們定義了一個(gè)博客內(nèi)容描述信息展示組件 Ext.ux.DescBox,它繼承自 Ext.Component 組件,并且自定義了 Get 和 Set 方法,同時(shí)重寫(xiě)了父類的 afterRender 方法,其中第一行的代碼 Ext.ux.DescBox.superclass.afterRender.apply(this, arguments);必須調(diào)用,指的是將子類的參數(shù)應(yīng)用到父類的構(gòu)造方法中,類似于 Java 程序中的 super() 方法;第二行代碼 this.description = this.getTargetEl().createChild(...)指在 Component 組件中創(chuàng)建一個(gè) HTML 標(biāo)簽 pre, 并將 value 的值放置于 pre 標(biāo)簽中。
事件處理:人機(jī)交互和 UI 組件之間的切換,需要事件來(lái)驅(qū)動(dòng)或觸發(fā),因此各 UI 組件都支持一系列特定的事件及其處理方法,可參閱 API 文檔 。示例中需要依靠葉子節(jié)點(diǎn)觸摸事件 leafitemtap 將顯示界面切換為 Detail Card,就需要在 NestedList 組件上注冊(cè)處理方法,其代碼為:
清單 7
- nestedList.on('leafitemtap', function(subList, subIdx, el, e,
- detailCard) {
- var ds = subList.getStore(), r = ds.getAt(subIdx);
- detailCard.setValue(r.get("description"));
- });
其回調(diào)函數(shù)的參數(shù)依次代表“觸控條目(item)所在 List 組件”,“觸控條目的 ID”,“觸控條目 element 對(duì)象”,“觸控事件對(duì)象”和“接下來(lái)要顯示的 Detail Card 組件對(duì)象”。
部署到 Apache Tomcat 6.x 進(jìn)行測(cè)試
編寫(xiě)好對(duì)應(yīng)的 HTML、JavaScript 和后臺(tái)處理的 Servlet 之后,可將動(dòng)態(tài) Web 工程打包成為標(biāo)準(zhǔn)的 WAR 包,部署至 Tomcat 的 webapp 文件夾,啟動(dòng)服務(wù)器;隨后打開(kāi) Android Virtual Devices,啟動(dòng)其中的瀏覽器程序,并在 URL 地址欄輸入 http://<localhost IP address>:8080/myblog/,便可以對(duì)該應(yīng)用進(jìn)行測(cè)試了,運(yùn)行的畫(huà)面如 圖 8 所示。由于 Sencha Touch 應(yīng)用的跨平臺(tái)性,使用其他任意一款基于 Webkit 內(nèi)核的瀏覽器,如 iPhone4 的 Safari,也能得到相關(guān)的測(cè)試結(jié)果,而不僅限于文中示例的 Android 設(shè)備瀏覽器。
圖 8 應(yīng)用運(yùn)行及測(cè)試畫(huà)面
開(kāi)發(fā)與原生程序一樣酷炫界面的 Web 移動(dòng)應(yīng)用,一直是 Web 開(kāi)發(fā)者的夢(mèng)想,Sencha Touch 移動(dòng) Web 開(kāi)發(fā)框架使得這一夢(mèng)想不再遙遠(yuǎn)。該框架以其豐富的 UI 組件,個(gè)性化的動(dòng)畫(huà)效果,穩(wěn)定的數(shù)據(jù)及事件處理機(jī)制,易擴(kuò)展的編程模型,在移動(dòng) Web 應(yīng)用這個(gè)新領(lǐng)域嶄露頭角。本文利用一個(gè)博客瀏覽程序簡(jiǎn)要介紹了利用該框架編寫(xiě)程序的流程及基本方法,然而距離一個(gè)成熟的 Web 應(yīng)用還有相當(dāng)?shù)木嚯x,如用戶登錄的安全性、多用戶并發(fā)時(shí)后臺(tái)的伸縮性以及客戶端 JavaScript 的性能都有待提高,因此值得廣大開(kāi)發(fā)者深入的學(xué)習(xí)及實(shí)踐。