使用history.pushState()将历史记录两次推送到历史记录后未触发Popstate事件

时间:2016-08-05 08:43:18

标签: javascript browser-history event-listener pushstate popstate

我正在开设一个电子商店,在iframe中页面顶部打开商品。我正在使用

history.pushState(stateObj, "page 2", http://localhost:8888/product-category/tyger/vara-tyger/?view=product&item=test-4);

为了让客户复制当前网址并使用它来转到当前页面,并在iframe中打开该项目。另外,我正在使用

window.addEventListener('popstate', manageHistory);

function manageHistory(event) {
    if (!has_gone_back) {
        var iframeOpen = false;
        has_gone_back = true;
    }
    else {
        var iframeOpen = true;
        has_gone_back = false;
    }
}

为了让客户使用浏览器的后退和前进按钮进行导航(关闭和打开iframe)。

但是,当打开一个产品(调用history.pushState一次),使用浏览器的后退按钮,打开另一个产品(再次调用history.pushState),然后再返回时,manageHistory()是不叫。客户被带到第一个打开的产品,但如果再次按下,则会调用manageHistory()

我希望在按下第二个打开的产品页面时调用manageHistory(),以便添加代码以便在按下时将客户重定向到类别的起始页面。

我已尝试为已打开的产品添加事件侦听器,也仅为第一个添加事件侦听器。任何想法可能是什么问题?

1 个答案:

答案 0 :(得分:2)

来自https://developer.mozilla.org/en-US/docs/Web/Events/popstate

  

请注意,只调用history.pushState()或history.replaceState()不会触发popstate事件。 popstate事件只能通过执行浏览器操作来触发,例如单击后退按钮(或在JavaScript中调用history.back())。

您可以覆盖popStatereplaceState,但通常更好的办法是创建一个设置网址然后触发处理程序功能的包装器。

像这样......

function urlChangeHandler() {
  var url = window.location.href;

  // Whatever you want to do...
}

// Handle initial url:
urlChangeHandler();

window.addEventListener('popstate', urlChangeHandler);

var urlState = {
  push: function(url) {
    window.history.pushState(null, null, url);
    urlChangeHandler();
  },
  replace: function(url) {
    window.history.replaceState(null, null, url);
    urlChangeHandler();
  }
}

我的一个项目中有一个类似的文件,它根据#hash更新数据存储...

import tree from './state'


// No need for react-router for such a simple application.

function hashChangeHandler(commit) {
  return () => {
    const hash = window.location.hash.substr(1);

    const cursor = tree.select('activeContactIndex');
    const createCursor = tree.select('createNewContact');

    cursor.set(null);
    createCursor.set(false);

    (() => {
      if(!hash.length) {
        // Clean up the url (remove the hash if there is nothing after it):
        window.history.replaceState(null, null, window.location.pathname);
        return;
      }

      if(hash === 'new') {
        createCursor.set(true);
        return;
      }

      const index = parseInt(hash, 10);
      if(!isNaN(index)) {
        cursor.set(index);
      }
    })();
    commit && tree.commit();
  }
}

// Handle initial url:
hashChangeHandler(true)();

// Handle manual changes of the hash in the url:
window.addEventListener('hashchange', hashChangeHandler(true));

function createHash(location) {
  return (location !== null) ? `#${location}` : window.location.pathname;
}

module.exports = {
  push: (location, commit=true) => {
    window.history.pushState(null, null, createHash(location));
    hashChangeHandler(commit)();
  },
  replace: (location, commit=true) => {
    window.history.replaceState(null, null, createHash(location));
    hashChangeHandler(commit)();
  }
}