HTML 5 历史 API 与 PopState 和 AJAX 不断重新加载页面

HTML 5 History API with PopState and AJAX keeps reloading the page

我目前正在通过 Ajax 将数据加载到页面上,通过 pushState 更新 url,没有错误。并且 popstate returns 将完整对象输入控制台 — 以供查看。

我正处于前进和后退按钮部分工作的位置,这意味着,有时它会在 url 更改时重新显示内容,但大多数时候它只是重新加载正在停止的页面应用程序流畅。

一直在无休止地尝试让事情正常进行,但没有成功:(

我只是不明白为什么页面不断重新加载并返回到第一个实例。

我认为这可能与第一次查看页面时设置或未设置的状态有关。

我下面的代码,它在加载时触发 Ajax 请求,然后在用户更改下拉列表时更新页面内容。

$(function() {
"use strict";
var $results  = $('#results');

    // First dataset when page loads
    (function(){
      var x = 'https://swapi.co/api/people/';
      var swFirstCall = $.ajax({
        dataType: 'json',
        url: x,
        async: false
      });
      swFirstCall.done(function(data) {
        var template = $('#results_tpl').html();
        var html = Mustache.render(template, data);
        $results.html(html);
      });
    })();

    // New dataset based on selected category
    $(document).on('change', '#categories', function(e){
      e.preventDefault();
      var category = this.value; // get selected value
      var x = 'https://swapi.co/api/' + category + '/';
      var swChangeCall = $.ajax({
        dataType: 'json',
        url: x,
        async: false
      });
      swChangeCall.done(function(data) {
        var template = $('#results_tpl').html();
        var html = Mustache.render(template, data);
        $('#results').html(html);
        console.log("Category: " + category);

        window.history.pushState(
            // data
            // title
            // url
            category,
            category,
            window.location.pathname + '?page=' + category
            );
      });
    });
    window.addEventListener('popstate', function(event) {
          window.location.href = window.location.href;
          console.log(event);
          return(event);
    });
});

非常感谢任何帮助。我搜索了 Whosebug 和许多其他资源,但无法理解。

Codepen 如果对查看代码有帮助的话。

谢谢,巴里

您想要做的是在 pushState 时将 datacategory 变量存储在您的历史状态对象中。稍后,当您触发 popstate 事件(用户前后移动)时,您将拉出该状态。使用从 popstate 事件中获得的值,您将需要重新呈现页面。我对您的 pushState 函数和 popstate 处理程序进行了更改,以展示如何完成此操作。最后,您需要遵循评论之一中关于删除 ajax 调用中的 async: false 选项的建议 - 您没有理由需要像这样暂停其余的脚本执行。

编辑:忘记提及您需要在第一页加载时初始化您的状态对象。使用 replaceState 方法执行此操作,因为您不想创建另一个历史记录条目。相反,您想修改当前的历史记录条目以包含 categorydata,您希望在用户返回初始页面时 return 到。请参阅下面的 swFirstCall.done 方法,其中包含 replaceState 调用。

// ...

swFirstCall.done(function(data) {
  var template = $('#results_tpl').html();
  var html = Mustache.render(template, data);
  $results.html(html);
// initialize history state object
  window.history.replaceState(
    { category: 'Select Category', data  },
    null,
    '',
  );

// ...

window.history.pushState(
  // data
  // title
  // url
  { category, data },
  category,
  window.location.pathname + '?page=' + category
);

// ...

window.addEventListener('popstate', function(event) {
  window.location.pathname + '?page=' + event.state.category;
  var template = $('#results_tpl').html();
  var html = Mustache.render(template, event.state.data);
  $('#results').html(html);
  $('#categories').val(event.state.category);
});

// ..