请使用firefox,chrome等最新浏览器浏览本站。

单页应用实现方式——PJAX(ajax+pushstate)

html5 阿豹 341次浏览 0个评论 扫描二维码

实现单页应用开发,1.要做到页面无刷新 2.通过路由进行页面切换。
对于第一点我们使用ajax加载数据。第二点我们可以使用html5 history API中的history.pushState和history.replaceState实现.
以下是history相关api的使用:

history.pushState(),history.replaceState()

history.pushState方法接受三个参数,依次为:

state 一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null
title 新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填nul
url 新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。

注意,pushState方法不会触发页面刷新。如果哟设置了一个非同域的网址,则会报错

假定当前网址是best-html5.com/a.html,我们使用pushState方法在浏览记录(history对象)中添加一个新记录。

var stateObj = { title: "page2", url: "page2.html" };
history.pushState(stateObj, "page 2", "page2.html");

添加上面这个新记录后,浏览器地址栏立刻显示best-html5.com/page2.html,但并不会跳转到page2.html,甚至也不会检查page2.html是否存在,它只是成为浏览历史中的最新记录。
history.replaceState方法的参数与pushState方法一模一样,区别是它修改浏览历史中当前页面的值

history.state属性

history.state属性保存当前页面的state对象。

history.pushState({page: 1}, "title 1", "?page=1");
history.state
// { page: 1 }

popstate事件

每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。需要注意的是,仅仅调用pushState方法或replaceState方法 ,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用JavaScript调用back、forward、go方法时才会触发。另外,该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。

使用的时候,可以为popstate事件指定回调函数。这个回调函数的参数是一个event事件对象,它的state属性指向pushState和replaceState方法为当前url所提供的状态对象(即这两个方法的第一个参数)。

window.onpopstate = function(event) {
  console.log("state: " + JSON.stringify(event.state));
};

// 或者
window.addEventListener('popstate', function(event) {  
  console.log("state: " + JSON.stringify(event.state));  
});

上面代码中的event.state,就是通过pushState和replaceState方法,为当前url绑定的state对象。

这个state对象也可以直接通过history对象读取。

var currentState = history.state;

另外,需要注意的是,当页面第一次加载的时候,在onload事件发生后,Chrome和Safari浏览器(Webkit核心)会触发popstate事件,而Firefox和IE浏览器不会

什么是PJAX

PJAX的基本思路是,用户点击一个链接,通过ajax更新页面变化的部分,然后使用HTML5的pushState修改浏览器的URL地址,这样有效地避免了整个页面的重新加载。如果浏览器不支持history的两个新API或者JS被禁用了,那这个链接就只能跳转并重新刷新整个页面了。和传统的ajax设计稍微不同,ajax通常是从后台获取JSON数据,然后由前端解析渲染,而PJAX请求的是一个在服务器上生成好的HTML碎片.

demo:

		var Unit = {
                        //判断浏览器是否支持history api
			support : {
				history : function(){
					if (!!(window.history && history.pushState)){
						return true;
					} else {
						return false;
					}
				}
			}
		}

		$(document).on("click", "a[data-pjax]", function(evt){

			evt.preventDefault(); 
			var uri=$(this).attr('href');
			var _html=ajax_Load(uri); 
			var newTitle = $(this).attr('data-title');
			if(Unit.support.history()){
				var state=({
					url: uri, 
					title: newTitle
				});
				window.history.pushState(state, newTitle, uri);
			}else{ 
				window.location.href="#!"+~fakeURI; 
			} 
			return false;
		});

		function ajax_Load(uri){
			$.ajax({
				url: uri,
			}).done(function(data) {
				$("#main").html(data);
			});
		}

		window.addEventListener('popstate', function(evt){
			var state = evt.state;
			ajax_Load(state.url);
		}, false);

线上库: jquery-pjax.js


喜欢 (5)or分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到