带有PopState和AJAX的HTML 5 History API不断重新加载页面 [英] HTML 5 History API with PopState and AJAX keeps reloading the page

查看:61
本文介绍了带有PopState和AJAX的HTML 5 History API不断重新加载页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在通过Ajax通过 pushState 更新网址将数据加载到页面上,没有错误。并且 popstate 将完整对象返回到控制台 - 用于查看目的。

I'm currently loading data onto the page via Ajax updating the url via pushState, no errors. And popstate returns the full object into the console — for viewing purposes.

我正处于前进和后退按钮部分工作,这意味着,有时它会在网址更改时重新显示内容,但大多数情况下它会简单地重新加载正在停止应用程序流畅的页面。

I'm at the point where the forward and back buttons work partially, meaning, sometimes it will reshow the content when the url changes, but most of the time it simple reloads the page which is stopping the smooth flow of the application.

一直在努力让事情发挥作用,但没有成功:(

Been working endless trying to get things to work, without success :(

我无法弄清楚为什么页面不断重新加载并恢复到第一个实例。

I just can't figure out why the page keeps reloading and reverting back to the first instance.

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

I think it might have something to do with the state being or not being set on first viewing of the page.

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

My code below, which fires an Ajax request on loading then updates the pages content when the dropdown is changed by the user.

$(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);
    });
});

任何帮助非常感谢。我搜索过Stackoverflow,但很多其他资源却无法理解。

Any help much appreciated. I've searched Stackoverflow, and many other resources though can't understand.

Codepen 如果它有助于查看代码。

Codepen if it helps viewing code.

谢谢,Barry

推荐答案

您要做的是存储数据类别 pushState 时历史状态对象中的变量。之后,当您触发 popstate 事件(用户前进和后退)时,您将拉出该状态。使用从 popstate 事件中获取的值,您将需要重新呈现页面。我对 pushState 函数和 popstate 处理程序进行了更改,以显示如何完成此操作。最后,您需要遵循有关在ajax调用中删除 async:false 选项的注释中的建议 - 您没有理由需要保留其余的你的脚本执行就像这样。

What you want to do is store the data and category variables in your history state object when you pushState. Later, you will then pull that state out when you trigger a popstate event (user goes back and forward). With the values you get out of the popstate event, you will then need to rerender the page. I made changes to your pushState function and your popstate handler to show how this can be done. Finally, you will want to follow the advice in one of the comments about removing the async: false option in your ajax call - there's no reason you need to hold up the rest of your script execution like this.

编辑:忘记提及你要在首页加载时初始化你的状态对象。使用 replaceState 方法执行此操作,因为您不想创建其他历史记录条目。相反,您希望修改当前历史记录条目以包含类别数据您希望在返回时用户返回初始页面。请参阅下面的 swFirstCall.done 方法,其中包含 replaceState 电话。

Forgot to mention that you'll want to initialize your state object on first page load. Use the replaceState method to do this as you don't want to create another history entry. Rather, you want to modify the current history entry to include the category and data you would want to return to when the user goes back to the initial page. See below for your swFirstCall.done method with the replaceState call included.

// ...

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);
});

// ..

这篇关于带有PopState和AJAX的HTML 5 History API不断重新加载页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆