利用history實現無刷新跳轉界面


  看標題是不是感覺很拽的樣子,其實沒什么啦,也就是時下常說的單頁面應用。這種web形式在如今的移動端十分流行,畢竟在移動端頻繁得去刷新界面不是很友好,而且還費流量。今天我們要做一個小的app(移動端),來揭秘history的秘密。首先我們了解一下核心方法:

  window.history.pushState:方法:為histroy建立歷史記錄,該方法傳入三個函數:1、對應url的信息2、下一個界面的title 3 、需要你動態改變的地址欄中德url.

  window.history.state:屬性:當前的history中的信息狀態。

  window.history.replaceState:方法:以本次信息替換之前的history內容記錄,傳入的參數與第一個相同。

  首先,你不必執着於上面的一些定義。在我第一次看到這些說明的時候我也是一頭霧水,真正了解他們是在使用它們之后。事不宜遲,我們首先創造出html結構來:

  要實現簡單的界面切換,我們首先要創建出三個界面,當然為了方便,這三個界面就是是三個div(a,b,c 整屏大,絕對定位)和一個按鈕(用來添加歷史內容記錄):

<!DOCTYPE html>
<html>
<head>
    <title>history back</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script type="text/javascript" src="zepto.js"></script>
    <link rel="stylesheet" type="text/css" href="history.css">
</head>
<body>
    <div class="a"><p>What we talk about when we talk about love</p><span>A</span></div>
    <div class="b none"><p>Quell nous sommes parlons lorsqur nous parlons d'amour</p><span>B</span></div>
    <div class="c none"><p>當我們在談論愛情的時候,我們在談論些什么</p><span>C</span></div>
    <button class="forward">FORWARD</button>
</body>
</html>

  翻頁效果,可以簡單一些,在這里,我做了動畫,利用css3的3d動畫屬性,打造簡單的動畫效果。如果你覺得麻煩,可以直接元素的顯示和隱藏,但在實際的項目中,我推薦利用動畫過度效果,這樣不僅提高客戶體驗,而且你可以利用到css3的許多新特新,對於web2.0時代的前端精英來說這是必修課。下面是切換效果的css代碼:

@-webkit-keyframes sliderightout{from{-webkit-transform:translateX(0px);}to{-webkit-transform:translateX(50%);}}
@-webkit-keyframes slideleftin{from{-webkit-transform:translateX(-50%);}to{-webkit-transform:translateX(0px);}}
@-webkit-keyframes slideleftout{from{-webkit-transform:translateX(0px);}to{-webkit-transform:translateX(-50%);}}
@-webkit-keyframes sliderightin{from{-webkit-transform:translateX(50%);}to{-webkit-transform:translateX(0px);}}

.slideleftout{-webkit-animation:slideleftout 350ms ease-in-out;}
.slideleftin{-webkit-animation:slideleftin 350ms ease-in-out;}
.sliderightout{-webkit-animation:sliderightout 350ms ease-in-out;}
.sliderightin{-webkit-animation:sliderightin 350ms ease-in-out;}
.animatestart{position:absolute;top:0;left:0;z-index:3;width:100%;height:100%;overflow-x:hidden}
.animatestart.page-container{overflow-x:hidden;-webkit-transform:translate3d(0,0,0);-webkit-backface-visibility:hidden;background-color:#f5f5f5}

  然后是控制界面各個元素的顯示位置的css代碼,排列組合各個界面(div p button span)。

*{
	padding: 0;
	margin: 0;
}
.none {
	display: none;
}
div {
  position: absolute;
  height: 100%;
  width: 100%;
  color: #fff;
}
div span {
	display: block;
	font-size: 6.5em;
	text-align: center;
}
div p {
	font-size: 1.2em;
}
button {
  position: absolute;
  height: 40px;
  width: 100px;
  border-radius: 6px;
  background: #fff;
  bottom: 50px;
  border: 0;
}
button.back {
  left: 20px;
}
button.forward {
	right: 20px;
}
.a {
background: #19a39e;
}

.b{
background: rgb(245, 81, 81);
}
.c{
background: rgb(71, 142, 30);
}

  接下來是重點,我們的思路是首先給瀏覽器的歷史填充記錄,這個需要手動完成,這也就是button的使命,因此,我們首先綁定forward按鈕:

//首先給history添加一條記錄,使得第一個界面和后來的界面看起來是永遠的以page=x結尾
window.history.pushState({info:'a'}, 'Page', '?page=a');
//數據源
var source = [
	{cls:'a', url:'?page=a'},
	{cls:'b', url:'?page=b'},
	{cls:'c', url:'?page=c'}
],
//數據源的下表,
k = 0,
//界面漲勢的屬性列表
index = ['a', 'b', 'c'],
//記錄每個界面跳轉的順序的列表
stoage = [];    

//綁定按鈕的tap事件,我們在移動端做測試,用的是tap,zepto會幫我們轉譯該事件
$('.forward').on('tap', function(){
	if(source[k]) {
		//取下一個界面的數據源
		var m = source[++k];
		//在這里填充history記錄,pushstate是方法是不會引起界面刷新的,但是卻會改變瀏覽器的回退/前進行為,執行這一步的時候可以看到地址欄中的url變化了。
		window.history.pushState({info:m.cls}, 'Page', m.url);
		//儲存該節目名稱到stoage列表中
		stoage.push(window.history.state.info);
		//下面是切換的動畫,因為這里力求簡單做的是一直向前走的動作,所以動畫是從右到左的切換順序
		$('.' + m.cls).removeClass('none').addClass("animatestart sliderightin");
		setTimeout(function(){ //動畫結束時重置class
            $('.'+ source[k -1].cls).addClass('none');
            $('.' + m.cls).removeClass('animatestart sliderightin');
        }, 350); 
	}
})

  上面做的事情,還僅僅是在界面中利用dom事件跳轉界面,要利用前進和后退按鈕實現無刷新跳轉節目我們需要偵聽popstate事件,也就是回退/前進行為的事件:

//利用stoage的存儲和index列表中的先后規則,放回動畫翻轉順,是從左到右,還是從右到左
function j() {
	var l = stoage.length;
	if(index.indexOf(stoage[l-2]) < index.indexOf(stoage[l-1])) {
		return 'animatestart sliderightin';
	}else{
		return 'animatestart slideleftin';
	}
}
//開始監聽瀏覽器的前進/后退行為
$(window).on('popstate', function(state) {
	//移除按鈕
	$('.forward').remove();
	//將本界面名稱存入stoage列表中
	stoage.push(window.history.state.info);
	//取得上一個界面的名稱
	var thiscls = stoage[stoage.length - 2];
	//取得當前界面的名稱
	var nextcls = stoage[stoage.length - 1];
	//對比兩個界面獲得動畫效果
	var cls = j();
	//執行動畫效果
	$('.' + nextcls).removeClass('none').addClass(cls);
		setTimeout(function(){ //動畫結束時重置clas
            $('.'+ thiscls).addClass('none');
            $('.' + nextcls).removeClass(cls);
        }, 350); 

});

  通過點擊按鈕,這時候看到,瀏覽器的回退按鈕已經可以啟用,我們點擊回退,觀察url的變化和界面的切換變化

  page=c變成了page=b,動畫效果是從左到右,界面就這樣切換成功,界面並無刷新,多試幾次。

A->B

B->C

  這樣我們就實現了點擊回退/前進按鈕實現單界面無刷新切換了。

  事情還有另一種做法,即使利用hash變化監聽onhashchange來實現無刷新的界面切換,你一定想到了backbone就是這樣做的。不過對於小一點的項目,我建議用'?'(傳值)不是'#'號(hash),因為無刷下跳轉意味着和利器ajax一起使用,使用‘?’號的好處是,即使用戶強制刷新了界面,我們也可以給后台傳參數,告訴后台我們正處於哪一個界面,需要什么樣的數據,從而和前段的ajax統一起來。因為?號代表search,刷新的時候給后台會傳入get類型的數據的。而#號(hash值)卻並不會這樣做。當然,你可以使用你的聰明才智改變這種情況,那就見仁見智了。


免責聲明!

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



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