jQuery Mobile組件:頁面和對話框
頁面剖析
jQuery Mobile的"page"模型被優(yōu)化為可以支持單個頁面或者頁面內嵌的"page".(譯注:這里的page和傳統(tǒng)意義上的頁面有所不同,在jquery mobile里指的是page模型或者結構,data-role="page"的一個div就是一個page)
這個模型的目標是允許開發(fā)者在創(chuàng)建站點時利用***實踐 — 傳統(tǒng)的鏈接就是起作用了,不需要任何特別配置 — 在創(chuàng)建 一個富客戶端,類似于本地應用程序可不能簡單的依靠標準的HTTP請求來達到.
page的結構
一個jQuery Mobile 的站點必須采用 HTML5 的'doctype' 標簽才能充分利用框架的特性.(一些早期的上網設備不知道 HTML5為安全的忽略'doctype'標簽 和很多定制屬性.) 在'head'標簽里,jQuery Mobile,jQuery和主題css文件等像如下開始:
- <!DOCTYPE html>
- <html>
- <head>
- <title>Page Title</title>
- <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
- <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script>
- <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>
- </head>
- <body>
- ...
- </body>
- </html>
在 標簽里, 每一個視圖或者'page'被一個元素(通常是 div)設置data-role="page" 屬性后所唯一標識:
- <div data-role="page">
- ...
- </div>
在"page"容器內部,任何有效的HTML標記都可以使用,但是對于典型的jQuery Mobile頁面而言,一個'page'的直接 子元素是 帶有 data-role 為 "header", "content", and "footer"的div.
- <div data-role="page">
- <div data-role="header">...</div>
- <div data-role="content">...</div>
- <div data-role="footer">...</div>
- </div>
完整的page模版
總的說來,這是標準的樣板page你應該使用的:
- <!DOCTYPE html>
- <html>
- <head>
- <title>Page Title</title>
- <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
- <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
- <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>
- </head>
- <body>
- <div data-role="page">
- <div data-role="header">
- <h1>Page Title</h1>
- </div><!-- /header -->
- <div data-role="content">
- <p>Page content goes here.</p>
- </div><!-- /content -->
- <div data-role="footer">
- <h4>Page Footer</h4>
- </div><!-- /footer -->
- </div><!-- /page -->
- </body>
- </html>
查看該模版
外部頁面鏈接
jQuery Mobile 自動化了創(chuàng)建ajax站點和程序的過程.
默認情況下,當你點擊一個鏈接時會指向一個外部頁面(如.products.html), 但是框架會解析該鏈接的 href屬性然后發(fā)出一個ajax請求(Hijax)并顯示正在加載的提示.
如果ajax請求成功,新頁面內容會添加到DOM當中,所有mobile widget都是自動初始化的,然后新頁面會動畫過渡顯示出來.
如果ajax請求失敗,框架會顯示一個小小的錯誤消息提示('e'調板的樣式),并會在一小段時間內消失, 并且不會破壞當前的導航流(譯注:即頁面不會刷新也不會對前進后退按鈕有影響). 錯誤頁面測試
內部頁面鏈接
單個HTML文檔可以包含多個'page',只需要在一個頁面包含 多個data-role="page"的div即可,每個pagediv必須由一個唯一的ID (id="foo") ,而鏈接到相應頁面使用錨記即可(href="#foo").當點擊一個鏈接時, 框架會尋找id為錨記href的內部'page'并顯示到當前界面中.
要注意如果你正在通過ajax從一個mobile頁面鏈接到一個含有多個內部頁面的頁面,你需要為該鏈接添加一個 rel="external" 或者 data-ajax="false" . 該屬性告知框架對頁面進行重新加載 ,url hash也將清零.這點十分關鍵,因為ajax 頁面使用 hash(#)來追蹤ajax歷史,當含有多個內部page的頁面使用hash 來指示內部page時會發(fā)生沖突.
舉例來說,一個指向含有多個內部page的頁面的鏈接會像這樣:
- <a href="multipage.html" rel="external">Multi-page link</a>
這兒有個2 'page'頁面的例子,由兩個jQuery Mobile div構建,每個div由其ID來導航,要注意 這些page上的ID只需要支持內部的頁面鏈接,如果每個頁面是分離的HTML文檔,這些ID則是可選的. 以下是兩個page,在body 元素里面.
- <body>
- <!-- Start of first page -->
- <div data-role="page" id="foo">
- <div data-role="header">
- <h1>Foo</h1>
- </div><!-- /header -->
- <div data-role="content">
- <p>I'm first in the source order so I'm shown as the page.</p>
- <p>View internal page called <a href="#bar">bar</a></p>
- </div><!-- /content -->
- <div data-role="footer">
- <h4>Page Footer</h4>
- </div><!-- /header -->
- </div><!-- /page -->
- <!-- Start of second page -->
- <div data-role="page" id="bar">
- <div data-role="header">
- <h1>Bar</h1>
- </div><!-- /header -->
- <div data-role="content">
- <p>I'm first in the source order so I'm shown as the page.</p>
- <p><a href="#foo">Back to foo</a></p>
- </div><!-- /content -->
- <div data-role="footer">
- <h4>Page Footer</h4>
- </div><!-- /header -->
- </div><!-- /page -->
- </body>
查看多page模板
請注意: 由于我們使用了hash來為所有ajax 'page' 追蹤歷史記錄,現(xiàn)目前來說, 在一個jQuery Mobile page里還不可能把鏈接作為普通的錨記(index.html#foo), 因為框架會尋找一個 ID 為 #foo 'page' 來跳轉,而不是像普通HTML頁面那樣滾動含有該ID的內容.
后退鏈接
如果你對一個a標簽使用 data-rel="back" 屬性,任何在上面的點擊都會模擬后退按鈕,而忽略它的href屬性. 這點在鏈接回一個已命名的頁面十分有用,比如當有一個到'home'鏈接或者當用javascript生成一個后退按鈕時, 或者一個按鈕用來關閉一個對話框.當在你的源代碼使用這個特性的時候,一定要提供一個有意義的href實際指出引用頁面的URL (這會使得該特性也能在C級瀏覽器中也能起作用). 同樣,請記住如果你只是單純使用一個后退過渡而不在歷史記錄中真正后退,你可以使用 data-direction="reverse"來替代.
重定向和鏈接到目錄
當鏈接至一個目錄地址時(比如用 href="typesofcats/"來替代 href="typesofcats/index.html"), 你必須提供一個后置 斜杠.這是因為jQuery Mobile假定在url中***一個"/" 后面的部分是一個文件名,jQuery Mobile會移除該部分,以便 在未來有頁面被引用時創(chuàng)建基地址.
然而,你可以通過返回已經指定了data-url屬性的page div來解決該問題. jQuery Mobile會使用該屬性的值來更新URL來替換過去請求的那個頁面. 這也允許你返回url的更改來作為重定向的結果,舉例來說,你可以提交一個表單到"/login.html",但是成功提交后返回一個 url "/account". 該工具允許你在一些程度上控制jQuery Mobile 的歷史記錄棧,以下是一些例子:
這個鏈接指向"docs-links-urltest/index.html",該鏈接是一個目錄里的索引頁 : Test Link 返回的頁面會用"docs/pages/docs-links-urltest/"(包含后置斜杠)來更新hash,這是通過那個頁面的data-url的值來完成的. 謹記這個值會替換整個hash,是否替換取決于你自己,當刷新或者深入鏈接時URL發(fā)出的請求能解析正確的頁面.#p#
頁面過渡
Page transitions
jQuery Mobile 框架包括六個以CSS為基礎的過渡, 可以應用于任何對象或頁面change事件, 適用于導航時以所選擇的過渡效果跳轉到新的一頁,以及為后退按鈕設置的逆向過渡效果。 默認情況下,框架采用從右至左的滑動(slide)的過渡效果。
要設置自定義的過渡效果,添加 data-transition 屬性到該鏈接。 可能的值包括:
- <a href="index.html" data-transition="pop">I'll pop</a>
這是一個動畫的網頁過渡效果,我們?yōu)殒溄犹砑恿艘粋€ data-transition屬性。
由于它使用CSS transform,這應該會在許多移動設備上得到硬件加速效果。
此外,你也可以強制指定一個data-direction="reverse" 用以在你的鏈接上實現(xiàn)"backwards"過渡。 注:(這是以前的data-back="true",這將繼續(xù)被支持到1.0版本)#p#
對話框
創(chuàng)建對話框
任何頁面鏈接中加入 data-rel="dialog"屬性后都可以被看作一個模態(tài)對話框。 當"dialog"屬性被應用,框架會為頁面增加一些樣式,包括圓角,頁邊空白,深色背景來讓對話框看起來像懸浮在頁面上。
- <a href="foo.html" data-rel="dialog">打開對話框</a>
打開對話框過渡
由于對話框是一個標準的“page”,它將以適用于所有page的標準過渡效果打開。 和其他page一樣,你可以指定你想要的任何過渡效果,只需要加入data-transition 屬性到該鏈接。 為了感覺更像對話框,我們建議你指定"pop", "slideup" 或者 "flip" 過渡效果。
- <a href="foo.html" data-rel="dialog" data-transition="pop">Open dialog</a>
data-transition="pop" data-transition="slidedown" data-transition="flip"關閉對話框
當點擊任何一個是在對話框中的鏈接時,框架會自動關閉對話框并過渡到請求的頁面, 就好像對話框是一個正常的page。要創(chuàng)建一個“取消”對話框按鈕,只需鏈接到觸發(fā)對話框打開的page, 然后添加 data-rel="back" 屬性,這種模式在non-JS的設備中同樣適用。
對于JavaScript生成的鏈接,您可以簡單地將href屬性設置為"#",并且添加 data-rel="back" 屬性, 你也可以調用對話框的close() 方法或者編程關閉對話框,例如: $('.ui-dialog').dialog('close').
歷史記錄與后退按鈕的行為
由于對話通常用于在一個頁面動作,框架不會在hash歷史中跟蹤對話框。 這意味著,對話框不會在你的瀏覽歷史記錄留下點擊一個頁面所應產生的效果。 例如,如果你在一個網頁中,點擊一個鏈接打開一個對話框,關閉對話框, 然后導航到另一個網頁,如果你此時點擊瀏覽器的后退按鈕,你將被導航回到***個頁面,而不是對話框。#p#
導航:Ajax, hashes & history
jQuery Mobile 的導航模型
(譯注:jqm的導航模型是jqm的核心所在,由于jqm中區(qū)分了頁面和page,所以在下文中要注意頁面和page出現(xiàn)時所代表的不同意思, 另下文中的“頁面更改”或者“頁面變化”大多指的是從當前頁面鏈接到jqm中的另一個page。)
在jQuery Mobile里一個'page'由一個設置了data-role="page"屬性的元素構成 (通常是div),通常里面包含"header", "content", 和 "footer",每個部分都可以包含普通的標簽,表單和jQuery Mobile的自定義widget.
頁面載入的基本工作流程如下:首先,用戶對頁面發(fā)起一個正常的HTTP請求, 隨后的'page'會被插入到當前頁面的DOM當中。正因為如此,DOM每次可能會有'page'的一個數(shù)字, 每個都可以通過連接到它的data-url 屬性來重新訪問。
當一個URL在初始化請求時,可能有一個或多個“page”在響應, 但只有***個將被顯示。 存儲多個“page”的優(yōu)勢是,它可以讓你預讀有可能被訪問靜態(tài)頁面。
Ajax驅動的頁面導航
jQuery Mobile中的所有導航都基于 location.hash的更改,只要有可能, 當前'page'到下一'page'的更改會平滑的過渡,無論該'page'是引進存在于DOM之中還是通過ajax自動的加載的。
hash值會在***個"真正"的頁面被正常完整加載時創(chuàng)建。hash始終會被維護為一個可用的URL, 所以任何jquery mobile中的 ‘page’都可以被標記為書簽或者引用為一個鏈接。要獲取非基于hash的URL,簡單的移除地址中的 #, 并刷新頁面即可。
一般來說,每當jQuery mobile中的一個鏈接被點擊時hash會發(fā)生變化。 當鏈接被點擊,jQuery mobile將確保該鏈接是引用一個本地URL, 如果是這樣,它會阻止鏈接的默認的點擊行為,并通過Ajax請求引用的網址。 當頁面成功返回,它將location.hash設置到新的頁面相關的URL 。
在框架內部,頁面的改變(已經存在于DOM之中或者通過ajax加載的)使用$.mobile.changePage() 函數(shù)。$.mobile.changePage()包括所有尋找頁面以及頁面間切換的邏輯, 和如何處理不同情況下請求的響應(比如頁面沒找到)。$.mobile.changePage() 可以在外部被調用,該函數(shù)接受如下的參數(shù)(to, transition, back, changeHash). to參數(shù)可以是一個string(如文件url或者當前頁面的元素ID),或是一個Array (***個數(shù)組元素為任意你想轉自的當前頁面中的page,第二個元素為轉去的頁面),或者一個object(含有如下屬性: url,type(get或post),和 data(用于序列化的參數(shù))),后者在加載含有表單數(shù)據(jù)時的頁面十分有用,transition 參數(shù)接受一個string來表示采用何種過渡,例如“slide”。 back 參數(shù)接受一個boolean值, 表示過渡是否應該前進或者相反。***,changeHash參數(shù)接受一個boolean值表示你是否要 根據(jù)一個成功的頁面更改來更新url。
$.mobile.changePage()函數(shù)在jQuery Mobile中很多地方都有用到。舉例來說,當一個鏈接被點擊時, 它的href屬性是正常的,然后$.mobile.changePage()會接手剩余的處理。的呢個表單被提交時, jQuery Mobile簡單地手機表單的屬性,并序列化它的數(shù)據(jù),然后$.mobile.changePage() 再次接手該次提交并響應。 同樣的,創(chuàng)建對話框的鏈接也是用$.mobile.changePage() 來打開相應引用頁 (只是不更新hash以保持對話框不會在歷史追蹤記錄里面)。
另一個jQuery Mobile 頁面導航模型中的關鍵要素是 base 元素,該元素被插入到head中, 在每次頁面變化時,該元素都會被修改以確保資源(css,js,圖片等)能正確的被引用和請求。 在不支持動態(tài)更新base元素瀏覽器(FF3.6)里,jQuery Mobile遍歷所有頁面引用的資源并 把它們的href和src加上基地址作為前綴。
hash的更改在一次獨立的點擊時發(fā)生,比如一個用戶點擊后退按鈕,會通過 hashchange事件進行處理, 該事件綁定到window對象(使用包含在jQuery Mobile中的Ben Alman的特殊事件插件)。當一個hash更改發(fā)生時 (***次頁面加載時同樣如此), hashchange 事件處理程序會發(fā)送 location.hash 給$.mobile.changePage()函數(shù), 以加載或者顯示引用的頁面。
一旦引用的頁面存在在DOM當中了, $.mobile.changePage()函數(shù)會在當前頁和引用頁間應用一個過渡, 以顯示頁面。頁面過渡會通過添加和移除指定了css動畫的class來實現(xiàn)。例如,在一個向左滑動的過渡效果中, 已經存在的頁面會被加上 名為 "slideleft" 和 "out" 的class,將要顯示的頁面會被加上"slideleft" 和 "in" 的class,同樣還有"ui-page-active" class來標記 新的頁面正要顯示了。當動畫完成后,"in" 和 "out" class 會被移除,而退出的頁面會被移除 "ui-page-active" class
開發(fā)者必須知道的基地址管理 :
jQuery Mobile使用生成絕對URL路徑和操作生成的元素的href屬性來管理http請求。 這兩種途徑的結合允許我們創(chuàng)建包含完整路徑信息URL來加載頁面,base元素將指示資源正確的被加載(css,圖片)。
TODO: update description of internal base and urlHistory objects
自動生成的頁面和子hash url
一些插件可能會選擇動態(tài)折斷頁面的內容為可導航的頁面,并通過層次化的鏈接來訪問。Listview插件就是其中一個例子, 該插件會折斷一個嵌套的UL(或OL)為單獨的頁面,每個都被賦予了data-url屬性以便于他們可以在jquery mobile中像其他頁面一樣 被鏈接。然赫然,為了鏈接到這些頁面中,生成的頁面必須首先被請求。因此,被插件自動生成的頁面使用如下特殊的data-url結構:<div data-url="page.html&subpageidentifier">
舉例來說,一個由listview插件生成的頁面可能會有一個像這樣的data-url屬性: data-url="artists.html&ui-page=listview-1"
當頁面被請求時,jquery mobile 知道在"&ui-page"處要分割 url并使用前面的正確url片段來發(fā)送一個HTTP請求。 至于在上文提到的listview例子中,url會像這樣:http://example.com/artists.html&ui-page=listview-1 ,而jquery mobile則會請求artists.html,然后會生成它的子頁面并顯示(創(chuàng)建一個data-url="artists.html&ui-page=listview-1"的div)。
請注意,元素的data-url的屬性包含完整的URL路徑,而不僅僅是&ui-page=后的片段。這允許jquery mobile使用 一個一致的機制來為頁面的data-url屬性匹配URL。
不使用ajax導航的情況
在某些情況下,正常的HTTP請求將被用來代替Ajax請求。一個情況就是當鏈接到外部網站時。 你可以使用如下屬性指定一個正常的HTTP請求:
rel=external
target (任何值都可以,如 "_blank")
表單提交
導航模型同樣會自動處理表單提交。更多細節(jié)請閱讀表單章節(jié)。
已知的限制
在非標準環(huán)境下由jquery mobile創(chuàng)建的頁面導航模型在一些條件下會出現(xiàn)一些限制需要你注意:
當鏈接至一個目錄地址時(比如用 href="typesofcats/"來替代 href="typesofcats/index.html"), 你必須提供一個后置 斜杠.這是因為jQuery Mobile假定在url中***一個"/" 后面的部分是一個文件名,jQuery Mobile會移除該部分,以便 在未來有頁面被引用時創(chuàng)建基地址.
任何在jQuery Mobile驅動的頁面中,唯一的資源引用都會放置在‘page’元素中(data-role="page")。 例如,樣式表和腳本的鏈接可以在div內被引用并指定應用于相應的頁面。然而, 更好的途徑是在頁面加載時用jquery mobile的頁面事件來觸發(fā)指定的 腳本。注: 你可以從服務器返回一個已經在標簽中指定了data-url屬性的頁面, jQuery Mobile會利用此來更新hash。這可以使你確保帶有斜杠的目錄路徑解析正確,因此也可以用于未來請求所需的基地址。
相反地,任何非唯一的資源(全局資源)應該在標簽中被引用, 或者至少在‘page’元素外面,以防止腳本重復運行。
"ui-page"關鍵詞用于子hash的rul引用,可以設置為任何你喜歡的值,以便配合你自己的URL結構。 該值存儲于 jQuery.mobile.subPageUrlKey中。#p#
鏈接格式示例
頁面主題化
jQuery Mobile 擁有一個豐富的 主題化系統(tǒng), 讓你可以完全控制如何顯示一個頁面的樣式。每個頁面部件(widget)都有詳細文檔可以參考, 但是讓我們先來看看一些高級別的例子來理解主題化是如何應用的。
data-theme 屬性可以用在header和footer中, 用任意字母來應用相應的主題調板。盡管 data-theme屬性可以被添加到內容容器中, 但是我們建議你把它添加到被分配了data-role="page"屬性的 div 或者容器中, 以確保背景色會在整個頁面中應用。
默認的主題樣式從多個調板種混搭得到,以創(chuàng)建視覺上的清晰感和高對比度感:
(譯注:以下為jQM內置主題的展示,故不翻譯,大家可以到jQM官網去看)