關於頁面轉場,這個必須得專門列出來講明一下,由於Jquery Mobile與普通的Web發開有一些區別,這個對於新手若是不瞭解的話,就會鑽到死衚衕。擼主前段時間就是很急躁地上手開發程序,結果在頁面轉場和參數傳遞的時候遇到各類奇怪的問題,最後幾乎打算刪掉html,改用Android原生layout來作程序了。javascript
不得不說,Jquery mobile給咱們這種作Java Web項目的人帶來了不少新鮮的玩意兒,雖然多多少少有些不適應,可是咱們得被動接受,長此以往就習慣。php
前面一對廢話結束,下面正式開始本節內容。css
頁面跳轉分爲兩種:Jquery mobile的跳轉和傳統的location跳轉,所謂入鄉隨俗,在使用了jquery mobile以後,我推薦儘可能用這種跳轉方式。先用例子簡單介紹,最後再說明jquery mobile跳轉的好處。html
有三個頁面(page1.html、page2.html、page3.html),主頁面是page1,點擊主頁面兩個按鈕能夠分別到page2和page3,[頁面2]按鈕使用<a>標籤的href屬性來定位page2的路徑,[頁面3]按鈕使用javascript的location來定位page3的路徑。java
【page1.html】jquery
<body> <div data-role="page" id="page1"> <div data-theme="b" data-role="header" data-position="fixed"> <h3> 頁面1 </h3> </div> <div data-role="content"> <a data-role="button" href="page2.html"> 頁面2 </a> <script> function goPage3(){ window.location = "page3.html"; } </script> <a data-role="button" href="#" onclick="goPage3()"> 頁面3 </a> </div> </div> </body>
【page2.html】web
<body> <div data-role="page" id="page2"> <div data-theme="b" data-role="header" data-position="fixed"> <a data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back">返回</a> <h3> 頁面2 </h3> </div> <div data-role="content"> 頁面2 </div> </div> </body>
【page3.html】ajax
<body> <div data-role="page" id="page3"> <div data-theme="b" data-role="header" data-position="fixed"> <a data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back">返回</a> <h3> 頁面3 </h3> </div> <div data-role="content"> 頁面3 </div> </div> </body>
編碼完成,看下具體效果圖:api
這是page1.html頁面,注意看瀏覽器導航路徑! 瀏覽器
這是page2.html,路徑有點特別
這是page3.html,路徑是直接指向page3的
從上面幾個圖能夠看出,跳轉到page2使用的是jquery mobile的AJAX轉場形式,而跳轉到page3使用的是咱們常見的location跳轉方式。
在page2頁面點擊查看源碼,你會發現源碼仍是page1頁面的。
Jquery Mobile跳轉可使用<a>標籤來完成,也能夠用jquery mobile自帶的chagePage方法完成。
<!-- 方式一 --> <a href="page2.html">頁面二</a> <!-- 方式二 --> <script> $.mobile.changePage("page2.html"); </script>
若是不想讓<a>標籤以Jquery Mobile形式跳轉,則須要增長一個屬性:data-ajax="false"
<!-- 方式一 --> <a href="page3.html" data-ajax="false">頁面三</a> <!-- 方式二 --> <script> window.location = "page3.html"; </script>
使用Jquery Mobile轉場容易,可是轉場後就有不少事項要注意了,否則你會遇到不少問題。
①AJAX只加載<body>標籤裏的內容
當用戶點擊一個jQuery Mobile驅動的網站的連接,那默認會經過Ajax請求頁面。(而不是是瀏覽器經過默認的連接方法家在整個頁面)。當請求發出之後,框架會接收到內容,可是他只會將請求的頁面的body 內容插入到DOM中(或者只是 data-role="page" 的容器),這就意味着head標籤中的元素不會被請求到。
這就意味着在HEAD中引用的腳本和樣式在用經過AJAX加載後不會起做用,只能經過普通的HTTP請求執行。當編寫jQuery Mobile 網站的腳本時,兩種狀況都要由於考慮。經過AJAX加載的頁面會無視head 中的內容是由於從新執行相同的JS的概率是很高的(由於整站的每一個頁面可能都引用一樣的JS文件)。
因此要想讓全部子頁面的js能成功被執行,要麼就將js寫到主頁面,要麼將js寫到子頁面的<body>標籤內。(這個我更推薦將js放到主頁面,由於同事發如今本身的pad上<body>中加入script沒效果)
②子頁面不支持頁面內跳轉
咱們知道Jquery支持一個html中包含多個<div data-role="page">,只要有id,就能夠進行頁面切換。
<div data-role="page" id="pageone"> <div data-role="content"> <a href="#pagetwo">Go to Page Two</a> </div> </div> <div data-role="page" id="pagetwo"> <div data-role="content"> <a href="#pageone">Go to Page One</a> </div> </div>
可是這裏有一個巨坑!我先前就是被這個坑困住了,幾乎到完全放棄:只有主頁面支持頁面內page跳轉,使用Jquery Mobile轉場的子頁面都不支持頁面內page跳轉!
簡單說明一下:
假設page1.html是入口主頁面,它裏面有兩個page(id爲page十一、page12)。
page1.html能夠跳轉到page2.html,page2.html也有倆page(id爲page2一、page22)。
那麼在page1.html頁面,page11能夠跳轉到page12;可是若是轉場到page2.html頁面,page21沒法跳轉到page22!
這個有一個解決辦法,就是禁用AJAX轉場,好比在<a>標籤中增長屬性data-ajax="false"。
<a href="page2.html" data-ajax="false">頁面二</a>
若是這樣,page2.html必須引入完整的相關javascript和css文件。
③ 使用 pageInit(),而不是$(document).ready()
(這段話直接摘自 中文API站 )你學jquery的第一件事就是在 $(document).ready()函數中寫代碼,因此一切都在dom元素加載後執行。可是在jQuery Mobile中,AJAX會根據你的導航把每一個頁面的內容加載到dom中,而DOM ready 函數只是在第一個頁面加載完畢纔會執行。因此要在任何新頁面加載並建立是執行腳本,就須要綁定pageinit事件。
之因此要這麼作的緣由就是第①點,Jquery Mobile的跳轉是基於AJAX的,因此ready()事件只會在主頁面出發,子頁面徹底沒效果。
要想在子頁面加載時作一些初始化操做就得這樣寫:
$(document).on("pageinit","#page1",function(){
//do something...
});
"#page1"是指須要初始化哪一個page,因此這裏引出了下一個注意事項「每一個page的id必定要惟一」!
④每一個page的id必定要惟一
若是整個應用都是使用Jquery mobile轉場的話,那麼全部html中的<div data-role="page" id="">這個id值都要不同!只有ID不同,才能讓每一個頁面正確執行pageinit事件。
$(document).on("pageinit","#page1",function(){ //do something... }); $(document).on("pageinit","#page2",function(){ //do something... }); $(document).on("pageinit","#page3",function(){ //do something... });
⑤找頁面元素最好從page id開始找
第④點說了,page的id必定要惟一,可是page下的元素的id在不一樣html頁面是能夠重複的,爲了準確找到page子元素,我建議按照下面這樣的格式來尋找:[$("page id").find("子元素")]
<script> $("#page1").find("#header_h1").html("頁面一"); $("#page2").find("#header_h1").html("頁面二"); $("#page3").find("#header_h1").html("頁面三"); </script>
在作java web項目的時候,徹底不擔憂參數傳遞問題,可是HTML開發卻跟java web有很大區別。
首先說明window.location的形式跳轉到第二個頁面如何接收參數。
通常跳轉都是一個URL,而在URL後面接一個問號字符串"?xx=xx"就是帶參數傳遞了,在第二個頁面的時候能夠獲取當前頁面的URL,再解析問號後面的字符串便可得到指定參數。
假設這是page1.html的跳轉URL
<script> window.location = "page2.html?id=123&name=ABC"; </script>
在page2.html能夠這樣得到參數:
<script> var data = $.getUrlParam(window.location.href); alert("URL:"+window.location.href); alert("ID:"+data.id); alert("NAME:"+data.name); </script>
我封裝了一個$.getUrlParam方法用於解析URL參數:
<script> /** * 解析URL中的參數 * @param {url路徑} string * @returns {返回object<key,value>} */ $.getUrlParam = function(string) { var obj = new Object(); if (string.indexOf("?") != -1) { var string = string.substr(string.indexOf("?") + 1); var strs = string.split("&"); for (var i = 0; i < strs.length; i++) { var tempArr = strs[i].split("="); obj[tempArr[0]] = tempArr[1]; } } return obj; } </script>
而若是用Jquery Mobile的形式傳遞的話,則須要瞭解一個事件[pagebeforechange],這個事件簡單說就是在頁面轉場時觸發,此時轉場頁面元素已經到位,你在這個事件內直接操做轉場頁面元素或js方法以達到參數傳遞的做用。
我是從 這個博客 看到這種傳遞參數的方式的。
<script> $(document).unbind("pagebeforechange").bind("pagebeforechange", function(e, data) { if (typeof data.toPage != "string") { var url = $.mobile.path.parseUrl(e.target.baseURI); if (url.href.search(pageUrl) != -1) { //從url中解析參數 var params = $.getUrlParam(url.href); var page = $(e.target).find("#子頁面page ID"); page.find("#id").val(params.id); page.find("#name").html(params.name); } } } $.mobile.changePage("page2.html?id=123&name=ABC"); </script>
注:上面代碼經過[$(e.target).find("#子頁面page ID");]獲取的是page2.html的page id,隨後再經過它找到本身的子元素進行數據初始化操做。
想了解更多pagebeforechange事件,能夠自行網上搜索關鍵字查看,這類文章很是多!
目前我還有兩個疑問:
一個是經過[$.mobile.changePage]跳轉時,能夠傳入data屬性,這個我不知道子頁面怎麼去接收。
$.mobile.changePage({
url: "searchresults.php",
type: "get",
data: $("form#search").serialize()
});
第二個是若是用<form action="page2.html">...</form>的形式提交表單數據到page2,不知道這個怎麼接收參數。
由於目前用得還不深,等隨後有相關開發需求再研究吧。