Backbine.js實戰第七章----導航控制器
在前面的章節中曾提到,Backbone框架的最佳應用場景是構建一個邏輯複雜的單頁應用,即單頁富應用。隨著人名對這種應用的喜愛,希望提供或蒐藏應用在某一階段的URL或錨點地址,方便日後直接進入這個階段的功能頁。
為了滿足這種需求,實現在單頁富應用中通過錨點或特殊格式的URL完成可分享、可收藏的功能,Backbone框架中提供了兩個重要的模型——導航控制器(router)和歷史(history),router封裝了相容各類瀏覽器history的方案,通過使用瀏覽器的hash物件和HTML5中的pushState方法,將某階段特殊的URL或錨點地址與既定的事件(event)或函式(action)相繫結。輸入這些URL地址時,對應完成不同的功能,從而實現在單頁富應用中分享和收藏的功能。
7.1 瀏覽器導航基礎
在正式介紹Backbone中的導航控制器(router)之前,有必要了解下瀏覽器的導航功能基礎知識,包含瀏覽器視窗(window)的history、HTML5中history API和location物件。瞭解這些基礎知識,有利於對Backbone中的導航控制器工作原理的理解和掌握。
7.1.1 history物件
在編寫JavaScript程式碼中,經常用到history物件,它的功能是儲存瀏覽器的歷史瀏覽記錄。出於對使用者隱私和安全性的考慮,history物件可以使用的方法相對較少,其中有兩個比較常用的方法——back和forward。
(1)back方法的功能是返回瀏覽器歷史記錄中當前頁的上一頁,與瀏覽器的“後退”按鈕功能相同,呼叫格式如下。
window.history.back();
(2)forward方法的功能是進入瀏覽器歷史記錄中當前頁的下一頁,與瀏覽器的“前進”按鈕功能相同,呼叫格式如下。
window.history.forward();
接下來通過一個簡單示例進行介紹。
示例 7-1 history物件的方法
1.功能描述
在專案中,新建兩個用於互訪的頁面7-1-a.html和7-1-b.html。在第一個頁面中新增一個按鈕和一個超級連結元素,如果在history物件中存在已前進的歷史記錄,則隱藏超級連結元素,否則隱藏按鈕。單擊超連結元素時,進入7-1-b.html頁面,單擊按鈕時,進入歷史記錄中當前頁的下一頁。在第二個頁面中新增一個按鈕,單擊該按鈕時,返回歷史記錄中當前頁的上一頁。
檔案7-1-a.html內容
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
<style type="text/css">
body{
font-size:12px;
}
</style>
</head>
<body>
<input type="button" id="btnforward" value="前進" onclick="window.history.forward();">
<a href="7-1-b.html" id="lnkforward">前進</a>
</body>
<script type="text/javascript">
var $obj_wh = window.history;
if($obj_wh.length>2){
$("#lnkforward").css("display","none");
}else{
$("#btnforward").css("display","none");
}
</script>
</html>
檔案7-1-b.html內容
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
<style type="text/css">
body{
font-size:12px;
}
</style>
</head>
<body>
<input type="button" value="後退" onclick="window.history.back();"/>
</body>
</html>
2.原始碼分析
在本示例第一個頁面的JavaScript程式碼中,首先定義一個名為“$obj_wh”的變數用於儲存history物件。該物件的length值大於2時,表示在該物件中已存在當前頁的下一頁連線。通過history物件length值跟蹤發現。首次開啟瀏覽器時,該屬性值為1,而瀏覽第一個頁面地址時,該屬性值又變為2。可見,每瀏覽一個新的地址時,都會向history物件中新增一條記錄,而對應的length屬性值有會相應地增加1。所以該屬性值大於2時,表名瀏覽器已開啟過本示例的第二個頁面,因此就會隱藏連結元素,顯示“前進”按鈕。
在第一個頁面新增“前進”按鈕時繫結onclick事件,單擊該按鈕時,將呼叫history物件中的forward方法直接進入當前頁歷史記錄中的下一頁。
在第二個頁面新增“後退”按鈕時繫結onclick事件,單擊該按鈕時,將呼叫history物件中的back方法直接進入當前頁歷史記錄的上一頁。
在history物件中,呼叫該物件forward和back方法分別實現頁面的前進和後退功能外,直接呼叫物件的go方法,也能實現頁面的前進和後退功能,呼叫格式如下。
winodw.history.go(n);
其中,引數n為一個整數,大於0時表示前進,小於0時表示後退,因此,如果是用於實現頁面的前進功能,下面程式碼是等價的。
window.history.forward();
等價於:
window.history.go(1);
如果是用於實現頁面的後退功能,則下列程式碼也是等價的。
window.history.back();
等價於:
window.history.go(-1);
7.1.2 HTML5中history物件API
上一節針對HTML4標準介紹了history物件的常用方法。HTML5基於原有物件方法新增了兩個實用的API方法。
(1)pushState方法:功能是向歷史記錄堆疊的頂部新增一條記錄,常用於實現頁面的無重新整理跳轉,其呼叫格式如下。
window.history.pushState(data,title[,url]);
其中,data參數列示在新增記錄時傳遞的資料物件,該物件通常為JSON格式的字串;引數title為頁面顯示的標題,可選項引數為頁面跳轉地址,預設值為當前頁地址。
(2)replaceState方法:功能是修改當前的歷史記錄值,其呼叫格式如下。
window.history.replaceState(data,title[,url]);
其中,各個從引數的使用說明與pushState方法相同,不再贅述。
此外,history物件還有一個重要的state屬性,通過該屬性可以獲取使用pushState方法新增的實體物件的內容,即在使用pushState方法增加時data引數的實體值,它的呼叫格式如下。
window.history.state;
目前,各個瀏覽器對HTML5標準支援不全面,在使用history物件兩個新增的API方法時,首先需要檢測瀏覽器對它的支援狀態,檢測程式碼如下。
function supports_history_api(){
return !!(window.history&&history.pushState);
}
呼叫上面的自定義函式,如果返回值為true,表示支援history物件新增的API方法,否則表示瀏覽器不支援history物件或新增的API方法。
接下來通過一個簡單示例進行介紹。
示例 7-2 HTML5中history物件的方法
1.功能描述
在專案中新建兩個頁面7-2-a.html和7-2-b.html用於互訪。在第一個頁面中,新增兩個<div>和<span>元素,呼叫history物件的pushState方法時,分別顯示history物件當前新增的歷史記錄實體總量和內容;在第二個頁面中,同樣新增兩個<div>he <span>元素,呼叫history物件的replaceState方法時,分別顯示history物件當前替換後的歷史記錄實體總量和內容。
檔案7-2-a.html內容
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
<style type="text/css">
div{
margin:5px 0px;
font-size:13px;
}
</style>
</head>
<body>
<div>記錄總量:<span id="divNum"></span></div>
<div>重新整理前:<span id="divShow"></span></div>
</body>
<script type="text/javascript">
var obj_a_state = {
Code:"10107",
Name:"皮卡丘",
Score:750
};
window.history.pushState(obj_a_state,"HTML5中history API方法","7-2-b.html");
$("#divNum").html(history.length);
$("#divShow").html(JSON.stringify(window.history.state));
</script>
</html>
檔案7-2-b.html內容
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
<style type="text/css">
div{
margin:5px 0px;
font-size:13px;
}
</style>
</head>
<body>
<div>記錄總量:<span id="divNum"></span></div>
<div>重新整理前:<span id="divShow"></span></div>
</body>
<script type="text/javascript">
var obj_b_state = {
Code:"10108",
Name:"傑尼龜",
Score:950
};
window.history.replaceState(obj_b_state,"HTML5中history API方法");
$("#divNum").html(history.length);
$("#divShow").html(JSON.stringify(window.history.state));
</script>
</html>
2.原始碼分析
在7-2-a.html頁面的JavaScript程式碼中,首先定義一個名稱為“obj_a_state”的JSON格式物件,然後呼叫history物件中的pushState方法將該物件的內容插入當前歷史記錄的頂部,作為當前歷史記錄的實體物件。同時設定titile和url引數值,使頁面在無重新整理的情況下,動態將當前的地址修改為url引數傳來的地址。最後,將history物件的記錄總數和state屬性內容分別顯示在頁面指定的元素中。
首次開啟7-2-a.html頁面後,雖然將當前頁的地址修改為url引數傳過來的地址,即將當前頁的地址修改為7-2-b.html,但僅限於修改,其實並沒有執行該地址。使用者此時單擊頁面導航條中的重新整理按鈕時,將真正瀏覽7-2-b.html頁。在該頁面的JavaScript程式碼中,呼叫history物件中的replaceState方法替換當前歷史記錄的物件,並將替換後的history物件記錄項總量和state屬性內容分別顯示在頁面指定的元素中。從上圖中可以看出,在記錄項總量未變的情況下,history物件state屬性內容發生了變化,說明替換成功。
7.1.3 location物件
在瀏覽器視窗(window)中,location物件的功能是管理瀏覽器的地址。相對於history物件而言,該物件擁有更多實用的屬性和方法,如最常用的href屬性和reload方法,前者可以獲取當前瀏覽器的地址,後者方法可以重新按地址載入當前頁面。此外,還能通過呼叫location物件其他屬性,獲取瀏覽器地址的各個組成部分,其屬性與地址組成部分對應關係如下圖所示。
從上圖可以看出,瀏覽器中URL地址的各個組成部分都可以通過呼叫location物件的屬性獲取,操作也十分方便。接下來通過一個簡單示例進行介紹。
示例 7-3 location物件的屬性和方法
1.功能描述
在頁面中新增一個<div>元素,用於顯示遍歷location物件後獲取的物件方法和各個屬性值的內容。另外新增兩個按鈕元素,單擊“過載”按鈕時,重新載入當前頁面,單擊“替換”按鈕時, 在當前頁中開啟一個新的URL地址。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
</head>
<body>
<div id="divShow"></div>
<input id="btnreload" type="button" value="過載" onclick="window.location.reload();"/>
<input id="btnreplace" type="button" value="替換" onclick="window.location.replace('http://www.baidu.com');"/>
</body>
<script type="text/javascript">
var $HTML = "";
var $obj_wl = window.location;
for(var idx in $obj_wl){
$HTML += "<b>" + idx + ":" + "</b>" + $obj_wl[idx] + "</br>";
}
$("#divShow").html($HTML);
</script>
</html>
2.原始碼分析
在本示例的JavaScript程式碼中,為了將遍歷後的location物件各屬性名稱和值顯示在頁面元素中,首先定義一個名為$HTML的變數,用於儲存內容,然後定義一個名為“$obj_wl”的變數,用於儲存location物件。接下來使用for語句遍歷location物件,並獲取物件的每個屬性名稱和對應屬性值,將他們儲存在$HTML中。最後將變數$HTML的內容顯示在頁面元素中。
在本示例的頁面程式碼中,新增兩個按鈕元素時就已繫結onclick事件。單擊“過載”按鈕時,將呼叫location物件的reload方法過載當前頁;單擊“替換”按鈕時,將呼叫location物件的replace方法,在當前頁面中開啟新頁面。
location物件中的reload和replace方法雖然都是在當前頁面重新載入,但兩者有本質的區別。前者是重新載入當前頁的URL地址,即進行當前頁的重新整理;後者是先將當前頁的URL地址進行替換,再在當前頁中載入替換後的URL地址。
此外,location物件中的hash屬性十分重要,該屬性易於設定和獲取,廣泛用於單頁應用中區域性效果的收藏,可以根據獲取的值執行不同的JavaScript程式碼,實現在單頁應用中無重新整理變換頁面的功能。該屬性也應用於下一節將要重點介紹的Backbone框架的導航器(router)中。
7.2 繫結導航地址
通過前面章節的學習,使我們掌握了瀏覽器(window)中history、location物件屬性和方法的使用。在Backbone框架中構建router類時,大量封裝了這兩個物件中的屬性和方法,將頁面特定的url或hash屬性與定義好的action或event相繫結。在位址列瀏覽這些URL時,觸發繫結的action對應的函式或執行相應的事件,可以實現無重新整理載入新內容,以及收藏特定URL片段的功能,接下來詳細介紹該功能的實現過程。
7.2.1 action方式繫結URL地址
所謂action方式,是將頁面特定的url或hash屬性與一個對應的函式(動作)相繫結,即在構建router類時,通過新增routes屬性,在該屬性中宣告url或hash屬性和函式的對應關係,這樣就完成了兩者間的繫結。一旦繫結完成,在瀏覽器中瀏覽對應的URL地址時,執行對應函式中的程式碼。接下來通過一個完整的示例進行介紹。
示例 7-4 action方式繫結URL地址
1.功能描述
在頁面中新增兩個<div>元素,第一個元素用於建立導航條,在該元素中新增多個超級連結<a>元素。單擊某個連結時,進入相應的URL地址。同時在第二個<div>元素中顯示對應的功能說明和傳回的引數值。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
</head>
<body>
<div>
<a href="">首頁</a> |
<a href="#search">查詢列表</a> |
<a href="#search/abc">關鍵字查詢</a> |
<a href="#search/abc/p2">頁碼關鍵字查詢</a> |
<a href="#error">其他頁</a> |
</div>
<div id="divShow"></div>
</body>
<script type="text/javascript">
var $divShow = $("#divShow");
var testrouter = Backbone.Router.extend({
routes:{
"":"main",
"search":"search_list",
"search/:key":"search_key",
"search/:key/p:page":"search_key_page",
"*search":"search_default"
},
main:function(){
$divShow.html("首頁");
},
search_list:function(){
$divShow.html("查詢列表");
},
search_key:function(key){
$divShow.html("查詢關鍵字為"+key+"記錄");
},
search_key_page:function(key,page){
$divShow.html("查詢關鍵字為"+key+"記錄,頁碼為"+page);
},
search_default:function(){
$divShow.html("其他頁");
}
});
var router = new testrouter();
Backbone.history.start();
</script>
</html>
2.原始碼分析
在本示例的JavaScript程式碼中,首先定義一個名為“$divShow”的變數,用於儲存顯示內容的頁面元素。在構建router模組時新增routes屬性,並在該屬性值中宣告需要監聽的URL地址列表。以key/value的形式宣告,key表示URL地址中hash屬性的規則,而value則表示當在瀏覽器位址列中執行該規則宣告的URL時,需要執行的動作(action)函式名。
然後,編寫URL地址中hash屬性規則執行的函式。在執行函式過程中,可以獲取URL地址中hash屬性規則傳來的實參值,並將該值顯示在頁面指定的元素中。
最後,由於URL地址中hash屬性的導航功能是由router和history類共同完成的。前者用於宣告和解析導航規則,並繫結對應的動作(action)函式名,後者用於監聽已繫結的URL地址變化,並觸發已繫結的動作(action)。因此,需要先例項化一個router類的物件router,然後通過呼叫history物件中的start方法啟動對URL地址變化的監聽。
相關文章
- CSS-實戰-梯形背景導航CSS
- Backbine.js實戰第二章----UnderscoreJS
- Backbine.js實戰第五章----模型集合JS模型
- BootstrapBlazor實戰 Menu 導航選單使用(1)bootBlazor
- BootstrapBlazor實戰 Menu 導航選單使用(2)bootBlazor
- 《iOS之導航控制器的使用圖解》iOS圖解
- Backbine.js實戰第六章----檢視JS
- Backbine.js實戰第三章----事件管理JS事件
- Swift3.0-學習之路之導航控制器Swift
- Backbine.js實戰第四章----資料模型JS模型
- 實現左側導航和橫向導航
- 【iOS開發-21】UINavigationController導航控制器初始化,導航控制器棧的push和pop跳轉理解...iOSUINavigationController
- 第 20 章 專案實戰--響應式導航[1]
- 自定義UINavigationController導航控制器實現傳統的框架(二)UINavigationController框架
- Tablayout實現導航欄TabLayout
- flutter 自定義tab導航-頂部導航-底部導航Flutter
- 導航控制器裡邊新增UIScrollView (automaticallyAdjustsScrollViewInsets)UIView
- web安全實踐系列導航Web
- 高德地圖駕車導航記憶體優化原理與實戰地圖記憶體優化
- DukuanCMS_網址導航,導航網站,網址導航原始碼網站原始碼
- 室內導航用什麼來實現?通過什麼可以實現導航功能?
- 如何實現園區路線導航?園區樓宇地圖導航如何實現?地圖
- 商場導航怎麼實現?怎樣製作商場導航圖?
- ReactNative實現地圖導航React地圖
- WPF/C#:實現導航功能C#
- 第七章、Groovy物件導向物件
- 如何在技術上實現室內導航?室內地圖導航怎麼實現?地圖
- 室內地圖導航是怎麼實現的?室內導航好做嗎?地圖
- 導航特效特效
- jquery導航jQuery
- Prism導航
- 路由導航路由
- 地下停車場怎麼導航,停車場導航技術怎麼實現
- AR 導航的幾種實現思路
- jQuery實現吸頂動畫導航欄jQuery動畫
- 安卓中如何實現滑動導航安卓
- IntersectionObserver + scrollIntoView 實現電梯導航ServerView
- 【WEB API專案實戰乾貨系列】- 導航篇(十足乾貨分享)WebAPI