我正在尝试使用 ajax 加载内容的 HTML5 历史 API。
我有一堆通过相对链接连接的测试页面。我有这个 JS,它处理对这些链接的点击。单击链接时,处理程序获取其 href 属性并将其传递给 ajaxLoadPage(),后者将来自请求页面的内容加载到当前页面的内容区域。(如果您正常请求,我的 PHP 页面设置为返回完整的 HTML 页面,但如果 ?fragment=true 附加到请求的 URL,则仅返回一部分内容。)
然后我的点击处理程序调用 history.pushState() 在地址栏中显示 URL 并将其添加到浏览器历史记录中。
$(document).ready(function(){
var content = $('#content');
var ajaxLoadPage = function (url) {
console.log('Loading ' + url + ' fragment');
content.load(url + '?fragment=true');
}
// Handle click event of all links with href not starting with http, https or #
$('a').not('[href^=http], [href^=https], [href^=#]').on('click', function(e){
e.preventDefault();
var href = $(this).attr('href');
ajaxLoadPage(href);
history.pushState({page:href}, null, href);
});
// This mostly works - only problem is when popstate happens and state is null
// e.g. when we try to go back to the initial page we loaded normally
$(window).bind('popstate', function(event){
console.log('Popstate');
var state = event.originalEvent.state;
console.log(state);
if (state !== null) {
if (state.page !== undefined) {
ajaxLoadPage(state.page);
}
}
});
});
当您使用 pushState 将 URL 添加到历史记录时,您还需要为 popstate 事件包含一个事件处理程序,以处理对后退或前进按钮的单击。(如果您不这样做,单击返回会在地址栏中显示您推送到历史记录的 URL,但页面未更新。)因此,我的 popstate 处理程序获取保存在我创建的每个条目的 state 属性中的 URL,并将其传递给 ajaxLoadPage 以加载适当的内容。
这适用于我的点击处理程序添加到历史记录的页面。但是当我“正常”请求浏览器添加到历史记录的页面时会发生什么?假设我正常登陆我的第一页,然后通过执行 ajax 加载的点击浏览我的网站 - 如果我然后尝试通过历史返回到该第一页,最后一次点击显示第一页的 URL,但没有'不在浏览器中加载页面。这是为什么?
我可以看出这与最后一个 popstate 事件的 state 属性有关。该事件的 state 属性为 null,因为只有通过 pushState() 或 replaceState() 添加到历史记录的条目才能为其赋值。但是我第一次加载页面是一个“正常”请求——为什么浏览器不只是退后一步并正常加载初始 URL?