我正在尝试使用 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?