首页 > 解决方案 > AJAX 导航 + window.history.pushState:“返回”浏览器按钮不起作用

问题描述

我创建了一个小 Javascript 工具来支持通过 AJAX(AjaxNav包含所有功能的全局对象)在 Plone 站点中部分加载内容。当然,我希望浏览器历史记录(后退和前进按钮)能够正常工作,所以我有以下小功能:

   var set_base_url = function (url) {  // important for local links (hash only)
        var head=null,
            base=$('html base').first();
        if (base) {
            base.attr('href', url);
            log('set base[href] to '+url);
        } else {
            $(document).add('<base>').attr('href', url);
            log('created <base> and set href to '+url);
        }

   var history_and_title = function (url, title, data) {
        var stateObj = {  // can be anything which is serializable, right?
            cnt: increased_state_counter()
            };
        if (typeof data.uid !== 'undefined') {
            stateObj['uid'] = data.uid;
        }
        if (title) {
            if (AjaxNav.options.development_mode) {
                title = '(AJAX) ' + title;
            }
            document.title = title;
        }
        if (url) {
            set_base_url(url);
            window.history.pushState(stateObj, '', url);
        } else {
            window.history.pushState(stateObj, '');
        }
    };
    AjaxNav.history_and_title = history_and_title;

这个函数被调用并且不会产生任何错误(至少我没有发现);但是当我尝试通过单击“返回”浏览器按钮或按下backspace键返回时,只有可见的 url 发生变化,但没有重新加载任何内容。我现在接受整页重新加载,但当然通过 AJAX 从历史记录重新加载页面会更好。

有没有明显的错误?

整个过程有点长(目前大约 850 行),因为通常无法知道目标 URL 是指定对象还是它的视图方法;因此我每个超链接最多尝试两个 UR,然后进行处理(替换内容、设置标题、event.preventDefault() 等),或者简单地返回true以加载整个页面。

标签: javascriptajaxbrowser-history

解决方案


您缺少popstate事件侦听器。在pushState向集合推送新的历史条目时,单击后退按钮将从历史集合中弹出一个状态。就像数组一样。事件popstate被设置为window对象,并且可以访问state您在pushState函数中设置的对象。

state为对象提供有关它应该在当前页面上做什么的信息是很有用的。例如,您必须获取哪些数据才能加载当前页面。

在您的代码中尝试下面的代码段,看看它输出了什么。

window.addEventListener('popstate', event => {
   const { state } = event;
   console.log(state);
});

推荐阅读