History
HTML5 History
传统的不使用?page=2
这样的参数。每一页就这样通过地址栏的
在history.pushState()
和 history.replaceState()
,以及window.onpopstate
。
APIs
我们可以使用如下方式来检测是否可用
export const supportsHistory = () => {
const ua = window.navigator.userAgent;
if (
(ua.indexOf("Android 2.") !== -1 || ua.indexOf("Android 4.0") !== -1) &&
ua.indexOf("Mobile Safari") !== -1 &&
ua.indexOf("Chrome") === -1 &&
ua.indexOf("Windows Phone") === -1
)
return false;
return window.history && "pushState" in window.history;
};
history.pushState()
它的完全体是 history.pushState(stateObject, title, url)
,包括三个参数。
第url
会关联在一起。
第
第?page=2
这样的参数风格的相对路径,它会自动以当前
调用 pushState()
方法将新生成一条历史记录,方便用浏览器的“后退”和“前进”来导航
history.replaceState()
它和 history.pushState()
方法基本相同,区别只有一点,history.replaceState()
不会新生成历史记录,而是将当前历史记录替换掉。
window.onpopstate
history.back()
等导航方法,且切换前后的两条历史记录都属于同一个网页文档,才会触发本事件。
上面的“同一个网页文档”请理解为document
是同一个,而不是指基础popstate
事件都不会触发。
popstate
事件是设计出来和前面的event.state
返还回来。
此外请注意,history.pushState()
及 history.replaceState()
本身调用时是不触发 popstate
事件的。
路由监听
首先,在服务器端添加对?page=3
将会输出对应页码的内容history.pushState()
,在任一次翻页的同时,也设置正确的带参数的
newURL = "?page=" + pageNow;
history.pushState(null, "", newURL);
到此,就解决了?page=3
退到 ?page=2
,会发现没有变化。按道理说,这时候也应该对应变化。这就要用到 popstate
事件了。为 window
添加 popstate
事件,加入这种导航变化时的处理:
$(window).on("popstate", function (event) {
// 取得之前通过pushState保存的state object,尽管本示例并不打算使用它。
// jQuery对event做了一层包装,需要通过originalEvent取得原生event。
var state = event.originalEvent.state, // 本示例直接取URL参数来处理
reg = /page=(\d+)/,
regMatch = reg.exec(location.search), // 第1页的时候既可以是 ?page=1,也可以根本没有page参数
pageNow = regMatch === null ? 1 : +regMatch[1];
updateByPage(pageNow);
});
这样,就完成了。这样看起来是否会觉得还挺容易的呢?在支持