Android+Jquery Mobile學習系列(4)-頁面跳轉及參數傳遞

關於頁面轉場,這個必須得專門列出來講明一下,由於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轉場注意事項

使用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,不知道這個怎麼接收參數。

由於目前用得還不深,等隨後有相關開發需求再研究吧。

相關文章
相關標籤/搜索