Javascript 我可以防止 history.popstate 在初始页面加载时触发吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5210034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:11:07  来源:igfitidea点击:

Can I prevent history.popstate from triggering on initial page-load?

javascriptjqueryhistorygetscriptpopstate

提问by jassa

I'm working on a site that serves content via AJAX.

我正在一个通过 AJAX 提供内容的网站上工作。

If you click an item in the menu, a content div gets updated with $.getresponse, nothing fancy.

如果你点击菜单中的一个项目,一个内容 div 会随着$.get响应更新,没什么特别的。

I'm implementing history.pushStateto allow navigation with the browser's back/forward button.

我正在实现history.pushState允许使用浏览器的后退/前进按钮导航。

I have the following to load content on history navigation:

我有以下内容可以加载历史导航中的内容:

$(function() {
    $(window).bind("popstate", function() {
        $.getScript(location.href); 
    });
});

The problem is, when a page is loaded for the first time, this function does $.getScriptso the page is loaded immediately again. The first time the page is loaded it renders the initial HTML view, then on the second load it renders the JS view, since its a JS request.

问题是,当第一次加载页面时,此函数会$.getScript立即再次加载页面。第一次加载页面时,它呈现初始 HTML 视图,然后在第二次加载时呈现 JS 视图,因为它是一个 JS 请求。

How could I prevent this event from firing on pages with HTML requests?

如何防止在带有 HTML 请求的页面上触发此事件?

回答by balupton

Using the native HTML5 History API you're going to run into some problems, every HTML5 browser handles the API a little bit differently so you can't just code it once and expect it to work without implementing workarounds. History.jsprovides a cross-browser API for the HTML5 History API and a optional hashchangefallback for HTML4 browsers if you want to go down that route.

使用本机 HTML5 History API 时,您会遇到一些问题,每个 HTML5 浏览器处理 API 的方式略有不同,因此您不能只编写一次代码并期望它在不实施变通方法的情况下正常工作。History.js为 HTML5 History API 提供了一个跨浏览器的 API,hashchange如果您想沿着这条路线走下去,则为 HTML4 浏览器提供了一个可选的回退。

For upgrading your website into a RIA/Ajax-Application you can use this code snippet: https://github.com/browserstate/ajaxify

要将您的网站升级为 RIA/Ajax 应用程序,您可以使用以下代码片段:https: //github.com/browserstate/ajaxify

Which is part of the longer article Intelligent State Handlingwhich goes into explanations about hashbang, hashes and the html5 history api.

这是一篇较长的智能状态处理文章的一部分,其中解释了有关 hashbang、哈希和 html5 历史 api 的解释。

Let me know if you need any further help :) Cheers.

如果您需要任何进一步的帮助,请告诉我 :) 干杯。

回答by mech

You need to get the event.originalEvent

你需要得到 event.originalEvent

// Somewhere in your previous code
if (history && history.pushState) {
  history.pushState({module:"leave"}, document.title, this.href);
}


$(window).bind("popstate", function(evt) {
  var state = evt.originalEvent.state;
  if (state && state.module === "leave") {
    $.getScript(location.href);
  }
});

回答by Oliver Nightingale

When the popstate event is fired on page load it will not have a state property in the event object. This allows you to check if the event is fired for a page load or not.

在页面加载时触发 popstate 事件时,事件对象中将没有 state 属性。这允许您检查是否为页面加载触发了事件。

window.onpopstate = function (event) {
  if (event.state) {
    // do your thing
  } else {
    // triggered by a page load
  }
}

回答by sydlawrence

When the browser first loads, it always fires a popstate event. So you need to determine if this popstate is yours or not.

当浏览器第一次加载时,它总是会触发一个 popstate 事件。所以你需要确定这个 popstate 是否是你的。

When you do your pushState, make sure you have a state object. That way you can check it later.

当您执行 pushState 时,请确保您有一个状态对象。这样你以后就可以检查了。

Then on the popstate handler, check the state object :)

然后在 popstate 处理程序上,检查状态对象 :)

$(function() {
    $(window).bind("popstate", function(data) {
        if (data.state.isMine)
            $.getScript(location.href); 
    });
});

// then add the state object
history.pushState({isMine:true},title,url);

Let me know if you need any more help :)

如果您需要更多帮助,请告诉我:)

回答by ghooz

I use the below approach to change the address bar and save the current state including the current HTML body, and I reload it on the back button click without any other AJAX call. All gets saved in your browser:

我使用下面的方法来更改地址栏并保存当前状态,包括当前的 HTML 正文,然后在没有任何其他 AJAX 调用的情况下单击后退按钮重新加载它。所有内容都保存在您的浏览器中:

<script type="text/javascript">
   $(document).ajaxComplete(function(ev, jqXHR, settings) {
      var stateObj = { url: settings.url, innerhtml: document.body.innerHTML };
      window.history.pushState(stateObj, settings.url, settings.url);
   });

   window.onpopstate = function (event) {
      var currentState = history.state;
      document.body.innerHTML = currentState.innerhtml;
   };
</script>