在《 使用 jQuery Mobile 與 HTML5 開發 Web App —— jQuery Mobile 基礎 》中,Kayo 曾經簡略介紹過 jQuery Mobile 的頁面組件,當時只是舉了一個簡單的例子說明一下頁面組件的情況,本文將會拓展說明頁面組件的具體細節。

?

一.頁面基礎

在 jQuery Mobile 中,頁面這個概念與傳統的 Web 頁面有一個很大的區別 —— jQuery Mobile 中的頁面可以是單個的頁面,也可以是一個頁面中內嵌多個 "Page" ,“Page” 是 jQuery Mobile 中的頁面,下面將會為大家詳細介紹它。

?

Page 是 jQuery Mobile 的重要組成部分,由 data-role="page" 屬性產生,每個 Page 由之前介紹過的 header , content , footer 組成,但這些元素并不是必須的,不過一個完整的頁面最好同時都有這些元素。下面舉一個例子,這也是《 使用 jQuery Mobile 與 HTML5 開發 Web App —— jQuery Mobile 基礎 》中的例子,為了方便大家閱讀,這里重新例舉一次。

          <!DOCTYPE html>
<html>
<head>
    <title>jQuery Mobile Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet"  />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
</head>
<body>
  
<div data-role="page" id="home">
  
    <div data-role="header">
        <h1>jQuery Mobile Demo</h1>
    </div>
  
    <div data-role="content">
        <p>主體內容</p>
    </div>
  
    <div data-role="footer">
        <h2>Footer</h2>
    </div>

</div>
</body>
</html>
        
?

?

效果:

使用 jQuery Mobile 與 HTML5 開發 Web App (九) —— jQuery Mobile 頁面與對話框

下面說明一下:

jQuery Mobile 網站必須使用 HTML5 的文檔聲明,使得這個網站能適用 HTML5 的特性,不支持這些特性的瀏覽器會安全地靜默忽略 HTML5 的文檔聲明和一些屬性。

HTML5 文檔聲明:

          <!DOCTYPE html>
        
?

?

在頁面 head 內,使用了 viewport 的 meta 標簽控制了頁面的縮放,例子中的 width=device- width, initial-scale=1 即控制頁面寬度等于屏幕寬度,頁面縮放比例為 1 ,這樣瀏覽器就不會隨意縮放頁面了。

?

二.多頁面結構

如上面所說,一個頁面中可以內嵌多個 Page ,每個 Page 需要一個 ID 標記,頁面間通過 “#ID” 的鏈接方式跳轉,除第一個 Page 外,其他 Page 會使用隱藏起來,當鏈接被點擊時, jQuery Mobile 會跳轉到相應的 Page ,這個過程會以 Ajax 的方式完成,把新頁面的內容加載到 DOM 中。

下面是一個多頁面結構的代碼參考:

          <!DOCTYPE html>
<html>
<head>
    <title>jQuery Mobile Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet"  />
    <script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
</head>
 
<body>
 
<div data-role="page" id="home">
 
    <header data-role="header">
        <h1>jQuery Mobile Demo</h1>
    </header>
 
    <div data-role="content">
 
    </div>
 
    <div data-role="footer">
        <h2>Demo By <a  target="_blank" style="text-decoration: none; ">Kayo</a></h2>
    </div>
</div>
 
<div data-role="page" id="page-2">
 
        <div data-role="header">
            <h1>Page 2</h1>
        </div><!-- /header -->
 
        <div data-role="content">
  
        </div>
 
        <div data-role="footer">
            <h2>Demo By <a  target="_blank" style="text-decoration: none; ">Kayo</a></h2>
        </div>
 
</div>
 
<div data-role="page" id="page-3">
 
        <div data-role="header">
            <h1>Page 3</h1>
        </div><!-- /header -->
 
        <div data-role="content">    
   
        </div>
 
        <div data-role="footer">
            <h2>Demo By <a  target="_blank" style="text-decoration: none; ">Kayo</a></h2>
        </div>
 
</div>
 
</body> 
</html>
        
?

?

三.Ajax 驅動的站點

jQuery Mobile 默認會以 Ajax 的方式構建網站和應用,因此,同一域名下的所有頁面的跳轉都會轉為 Ajax 請求,并會配合 CSS3 動畫作為頁面跳轉的過場。之所以采用這樣的機制,一方面是因為移動設備所能用的網絡速度相對 PC 來說會較低, Ajax 可以減少跳轉到新頁面所需的帶寬,另一方面, Ajax 配合 CSS3 動畫能做出原生 App 的用戶體驗。如:當用戶點擊一個鏈接時, jQuery Mobile 會分析該 url ,產生 Ajax 請求,并顯示一個正在加載的提示框,避免了刷新整個頁面。若該次 Ajax 請求成功,則會把新內容加載到 DOM 中,初始化所有組件,并顯示頁面過場動畫。若請求失敗,則會顯示一個錯誤提示框,并在幾秒后消失。

?

另外,帶有 rel="external" 屬性的鏈接不會通過 Ajax 方式加載,跳轉時整個頁面會被刷新。若需指定某個鏈接不需要 Ajax ,也可以為該鏈接添加 data-ajax="false" 屬性,這樣的鏈接也不會使用 Ajax 。關于 Ajax 的內容, Kayo 會在介紹配置 jQuery Mobile 時詳細介紹。

?

四.頁面轉場

jQuery Mobile 為自帶有一套基于 CSS3 的轉場效果,你可以為任何能觸發頁面跳轉的鏈接添加 data-transition 屬性來調整轉場動畫效果。這些效果基于 CSS3 的 transitions ,某些移動平臺對 transitions 的支持并不足夠,如果你的頁面在轉場時出現閃爍的情況, Kayo 建議你在 CSS 中加入下面這一條 CSS 規則:

          .ui-page { -webkit-backface-visibility: hidden; }
        

?

?

另外,若需要頁面翻轉等 3D 效果,瀏覽器必須支持 3D transforms ,若不支持(如安卓 2.x 系列),則會退化為淡出淡入的效果。

?

默認情況的轉場效果是“fade”,即淡出淡入,若需要自定義轉場效果,可以使用 data-transition 屬性,如把轉場效果改為“pop(彈出)”:

          <a href="#page2" data-role="button" data-transition="pop">dialog</a>
        
?

?

該屬性的具體取值可以查看本文末的完整 Demo,里面列舉了 data-transition 所有可取值。

小補充:控制轉場寬度:當轉場頁面的寬度過大時,翻轉等 3D 效果可能會過度消耗系統資源,因此開發者可以使用 $.mobile.maxTransitionWidth 控制轉場最大寬度,超過該寬度則不使用轉場動畫。 $.mobile.maxTransitionWidth 是配置 jQuery Mobile 默認值的方法,因為比較復雜,將會另外寫文章詳解,這里列出該方法僅供有經驗的開發者參考。

?

五.對話框

如下面的例子,為 Page 添加 data-rel="dialog" 屬性,可以把頁面表現為對話框的形式——增加圓角,外邊距,陰影和遮罩層。

          <a href="#page-2" data-role="button" data-rel="dialog" data-transition="fade" data-inline="true">dialog</a>
        
?

使用 jQuery Mobile 與 HTML5 開發 Web App (九) —— jQuery Mobile 頁面與對話框

對話框也是一個 Page ,因此也有轉場效果,不過默認的效果是“slide”,即滑動出現。

需要注意的是,對話框通常作為輔助頁面的用途(如登錄框,提示框),因此 jQuery Mobile 不會在歷史記錄的哈希值里記錄對話框。

?

六.jQuery Mobile 導航模型

看了上面的文字,也許你會對其中的內容感到迷惑!的確,jQuery Mobile 作為一套完善的移動前端解決方案,它的處理機制會比較復雜。這里 Kayo 介紹一下 jQuery Mobile 的導航模型,也就是 jQuery Mobile 的基本工作流程,了解完整的工作流程更有助于童鞋們理解上面的內容。

?

當一個 jQuery Mobile 文檔被打開時,Page 容器被請求,插入到頁面的 DOM 中,若頁面中有多個 Page ,則會插入多個 Page ,但只有第一個 Page 在頁面上會被直接顯示,其他 Page 會隱藏起來,直到用戶點擊相應的鏈接才會以 Ajax 的方式跳轉到另一個 Page 。

?

這就是 jQuery Mobile 導航的簡單描述,jQuery Mobile 也就是在頁面間跳轉并處理 DOM 的,而這套機制都是基于 location.hash 屬性的。當 jQuery Mobile 加載完第一個頁面時,它會以頁面相對于 url 的完整路徑產生 hash 值,Ajax 不改變當前 url ,而改變 hash 值則可以保證當前 url 能表示當前的頁面,如我們從 index.html 跳轉到管理頁面,則 url 也會更新為 index.html#admin(假設管理頁面與主頁在同一個 HTML 文檔中并且 id 為 admin),這樣這個 url 就能表示當前頁面,若我們需要收藏這個頁面,直接收藏即可。

于是最后就有了上面所說的 Ajax 驅動機制——當用戶點擊一個非外部鏈接時,hash 值發生變化,同時 jQuery Mobile 阻止鏈接的默認行為,并以 Ajax 的方式引入新內容,當新內容成功返回時更新 location.hash 的值,從而更新 url 。

?

現在整個導航模型以及 jQuery Mobile 的基本工作原理都已很清晰了,接下來再補充一點。在 jQuery Mobile 頁面的 head 中,加入了一個 base 標簽,該標簽的值指向當前頁面資源(圖片,css,js)的正確獲取路徑,當頁面變化時,base 的值也會作出相應的變化。

?

這里科普一下 base 標簽,下面引用 w3school 對 base 標簽的解釋:

[bq]
<base> 標簽為頁面上的所有鏈接規定默認地址或默認目標。
通常情況下,瀏覽器會從當前文檔的 URL 中提取相應的元素來填寫相對 URL 中的空白。
使用 <base> 標簽可以改變這一點。瀏覽器隨后將不再使用當前文檔的 URL,而使用指定的基本 URL 來解析所有的相對 URL。這其中包括 <a>、<img>、<link>、<form> 標簽中的 URL。
[/bq]

?

七.預讀取與緩存頁面

開發者可以通過 data-prefetch 屬性預讀取一個頁面,這樣當你打開一個文檔時,可以為另外一個文檔在本文檔中的鏈接添加 data-prefetch 來預先讀取它,這個文檔通常是用戶很有可能點擊的頁面,這樣對于提升用戶體驗具有不錯的效果。

?

那為什么不直接把兩頁面放在同一個文檔中呢?

因為如果把很多的 Page 放在一個文檔中,這個文檔的 DOM 會變得很大,這樣對于一些性能較差的移動設備來說會造成壓力,預讀取的方式則可以減少這種壓力。

比如我們需要緩存 page2.html (注意跟上面的 #page2 區分開來,這里的 page2.html 是獨立的一個 HTML 文檔),只需要在跳轉到 page2.html 的鏈接上添加 data-prefetch 屬性:

          <a href="Page2.html" data-prefetch>Page2</a>
        
?

?

但這仍然會有問題, jQuery Mobile 會通過 Ajax 的方式加載頁面,這樣一旦點擊的頁面多了,DOM 將會變得很大,于是 jQuery Mobile 還做了一個機制來應對這個情況——當一個頁面通過 Ajax 加載到 DOM 中后,jQuery Mobile 會標記這個頁面,當導航到其他頁面時,這個頁面會從 DOM 中移除,從而保持 DOM 的干凈。這個機制只適用于 Ajax 加載的其他文檔的頁面,同一頁面的多個 Page 通過 Ajax 顯示/隱藏并不適用于這個機制。

?

若需要緩存某個頁面,以便用戶從其他頁面重新回到該頁面時可以快速瀏覽可以使用 data-dom-cache="true" 屬性:

如需要緩存上面例子中的 page2.html

          <a href="Page2.html" data-prefetch data-dom-cache="true">Page2</a>
        
?

?

一旦緩存頁面會使 DOM 變得很大,建議開發者在網站上線前進行足夠的測試。

?

八.其他

多 Page 頁面中雖然把第一個容器加載作為第一個頁面,但實際上所有 Page 是同時存在于同一個文檔中,因此需要注意保持頁面中容器的 ID 唯一。

?

jQuery Mobile 通過 Ajax 請求頁面,但它只會將新頁面的 body 內容插入到 DOM 中,這意味著 head 部分引用的 js 對新內容無效,因此 Kayo 建議在每一個頁面都引用相同的 js ,即把所有的 js 都寫到同一文件中并在 head 中引用,并且這些 js 中用到的效果最好使用 live, delegate 等持續性方法匹配到元素中,這樣 js 中的效果對通過 Ajax 引入的新元素也有效。當然,jQuery Mobile 中的 js 的所有方法都已經采用了相似的辦法使到其對新元素也有效。當然,開發者也可以使用 pagecreate() 的方法為某一個頁面指定一個 js ,關于這個方法會在另外的文章中介紹。

?

九.完整 Demo

完整實例 Demo (建議使用 PC 上的 Firefox、Chrome 等現代瀏覽器和 IE9+ 或 Android , iPhone/iPad 的系統瀏覽器瀏覽)

?

原文由 Kayo Lee 發表,原文鏈接: http://kayosite.com/web-app-by-jquery-mobile-and-html5-page-dialog.html