SPA頁面初試


之前一直很好奇,SPA應用到底是怎么實現的,昨天無意間看到了有一篇介紹的文章,就想着來試一下水(以下根據我的理解所寫,可能會讓你看的雲里霧里,如果想加深了解,最好先了解下window.location.hash是什么東西)

DEMO:

<!DOCTYPE html>
<html>

	<head>
		<title>SPA</title>
		<style type="text/css">
			* {
				padding: 0px;
				margin: 0px;
			}
			
			html,
			body {
				height: 100%;
				width: 100%;
			}
			
			.pageview {
				width: 100%;
				height: 100%;
			}
		</style>
		<script type="text/javascript" src="js/jquery-3.1.1.js"></script>
		<script type="text/javascript">
			var states;
			var currentState;
			$(document).ready(function() {
					states = registState();
					currentState = init();
					//監聽hash路由變化
					window.addEventListener("hashchange", function() {
						var nextState;
						console.log(window.location.hash);
						//判斷地址是否為空,若為空,則默認到main-view頁面
						if(window.location.hash == "") {
							nextState = "main-view";
						} else {
							//若不為空,則獲取hash路由信息,得到下一個狀態
							nextState = window.location.hash.substring(1);
						}
						//判斷當前狀態是否注冊過(是有存在這個狀態)0g
						var validState = checkState(states, nextState);
						//若不存在,則返回當前狀態
						if(!validState) {
							console.log("you enter the false validState");
							window.location.hash = "#" + currentState;
							return;
						}
						$('#' + currentState).css("display", "none");
						$('#' + nextState).css("display", "block");
						currentState = nextState;
					})

				})
				//狀態注冊
			function registState() {
				var states = [];
				//狀態注冊
				$(".pageview").map(function() {
					return states.push($(this)[0].id);
				})
				return states;
			}
			//初始化,對用戶一開始輸入的url進行處理
			function init() {
				var currentState = window.location.hash.substring(1);
				if(currentState == "") {
					currentState = "main-view";
				}
				if(currentState != "main-view") {
					$('#main-view').css("display", "none");
					$('#' + currentState).css("display", "block");
				}
				return currentState;
			}
			//判斷狀態是否存在
			function checkState(states, nextState) {
				var tof = false;
				states.forEach(function(element) {
					if(element == nextState) {
						tof = true;
					}
				})
				return tof;
			}
		</script>
	</head>

	<body>
		<div class="pageview" style="background: #3b76c0" id="main-view">
			<h3>首頁</h3>
			<div title="-list-view" class="right-arrow"></div>
		</div>
		<div class="pageview" style="background: #58c03b;display: none" id="list-view">
			<h3>列表頁面</h3>
			<div class="left-arrow"></div>
			<div title="-detail-view" class="right-arrow"></div>
		</div>
		<div class="pageview" style="background: #c03b25;display: none" id="detail-view">
			<h3>列表詳情頁面</h3>
			<div class="left-arrow"></div>
		</div>
	</body>

</html>

  

其實,SPA的原理就是,一開始將一些必要的頁面都加載進來,當你在頁面輸入別的路由的時候,其實還是待在當前的頁面,只不過是他識別出你想要去的地址,然后將那個頁面的內容獲取到,替代掉當前頁面的內容,並且相應的改變url地址,這樣給人看起來就好像到了另一個頁面,實際上你還是在這個頁面里,沒有離開過.
比如,例如當前你在localhost:8080/index.html這個頁面時,你想跳轉到#list-view頁面(使用hashChange),或者你點擊某個跳轉按鈕要跳轉到那個頁面的時候,他先獲取你那個#list-view頁面的內容,然后將當前頁面的內容清除掉,然后再把list-view的內容呈現出來,並沒有跳轉到別的頁面,你從頭到尾都是在這個頁面里,不過url地址會變化,因此看起來就像你到了另一個頁面,這樣給人的用戶體驗特別好,因為不需要等待頁面加載過程.

說了這么多,我們來根據他的原理做一個SPA的小應用吧(里面的html和css代碼直接復制了我之前看的那個博客的作者的,因為懶得自己設計)

html代碼如下:

    <!DOCTYPE html> <html> <head> <title>SPA</title> <link rel="stylesheet" type="text/css" href="index.css" /> <script type="text/javascript" src="jquery-3.1.1.min.js"></script> <script type="text/javascript" src="spa.js"></script> </head> <body> <div class="pageview" style="background: #3b76c0" id="main-view"> <h3>首頁</h3> <div title="-list-view" class="right-arrow"></div> </div> <div class="pageview" style="background: #58c03b;display: none" id="list-view"> <h3>列表頁面</h3> <div class="left-arrow"></div> <div title="-detail-view" class="right-arrow"></div> </div> <div class="pageview" style="background: #c03b25;display: none" id="detail-view"> <h3>列表詳情頁面</h3> <div class="left-arrow"></div> </div> </body> </html>

在這里,我們先創建了三個div,第一個main-view的display不設置,其他的兩個display設置為node,這樣我們一開始進去就只能看到main-view這個頁面

之后,我們可以通過js代碼來模擬SPA對路由跳轉的處理

var states ; var currentState; $(document).ready(function() { states = registState(); currentState = init(); //監聽hash路由變化 window.addEventListener("hashchange", function() { var nextState; console.log(window.location.hash); //判斷地址是否為空,若為空,則默認到main-view頁面 if (window.location.hash == "") { nextState = "main-view"; } else { //若不為空,則獲取hash路由信息,得到下一個狀態 nextState = window.location.hash.substring(1); } //判斷當前狀態是否注冊過(是有存在這個狀態)0g var validState = checkState(states, nextState); //若不存在,則返回當前狀態 if (!validState) { console.log("you enter the false validState"); window.location.hash = "#" + currentState; return; } $('#'+ currentState).css("display", "none"); $('#'+ nextState).css("display", "block"); currentState = nextState; }) }) //狀態注冊 function registState() { var states = []; //狀態注冊 $(".pageview").map(function() { return states.push($(this)[0].id); }) return states; } //初始化,對用戶一開始輸入的url進行處理 function init() { var currentState = window.location.hash.substring(1); if (currentState == "") { currentState = "main-view"; } if (currentState != "main-view") { $('#main-view').css("display", "none"); $('#'+ currentState).css("display", "block"); } return currentState; } //判斷狀態是否存在 function checkState(states, nextState) { var tof = false; states.forEach(function(element) { if (element == nextState) { tof = true; } }) return tof; }

這里,我們首先將每一個div當做一個狀態,當用戶輸入的地址匹配了某個狀態之后,就呈現那個狀態所代表的頁面(每個div的狀態名我們設置為他們的id名字)

代碼我覺得還算比較清晰,首先,我們就先注冊這三個div的狀態(registState),然后根據用戶輸入的url地址來初始化頁面,返回匹配的那個狀態的頁面(init)。

並且,注冊一個hashchange事件,這個事件是當用戶輸入的hash地址變化后觸發,我們在里面獲取用戶的輸入地址,然后返回匹配的那個狀態的頁面,若沒有匹配的狀態,則返回上一個匹配的狀態。以下的截圖

值得一提的是,我里面替換頁面的做法是:將當前狀態的頁面的display設置為none,然后將下一個狀態的頁面的display設置為block,這樣就完成了頁面的替換以及路由的變換,而且不會導致路由的變化

初始頁面:

修改路由地址,修改為file:///C:/Users/chenjg/Desktop/Interest/SPA/index.html#list-view,可以看到頁面發送了相應的變化

輸入錯的地址,沒有匹配到合適的狀態,則恢復到上一個狀態:file:///C:/Users/chenjg/Desktop/Interest/SPA/index.html#list-vi

接下來打算繼續試下路由的嵌套,以及動態加載html文件作為路由的模塊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM