【问题标题】:How to current (not previous) state on windows popstate如何在 Windows popstate 上显示当前(不是以前)状态
【发布时间】:2015-09-10 22:34:52
【问题描述】:

我正在抓取 popstate,需要根据历史堆栈中的 current 和 originalEvent 做各种事情。但是,我不知道如何获取当前状态进行比较,但 originalEvent 有效。这是我的 JS 代码。第一个 IF 语句抛出了 e.state.id 未定义的异常...

$(window).on("popstate", function(e) {
        //check and compare current state
        if (e.state.id == 'something') {  // throws an exception
            *do something*
        } else if (e.originalEvent.state !== null) { //previous state exists?
            *do something*
        } else { //no previous state
            *do something*
        }
    });

仅供参考,推送状态设置为:

history.pushState({id: 'view'}, '', '/view');

【问题讨论】:

  • 你为什么不把它存储在每个 popstate 上?
  • 我需要获取我们要返回的内容的价值,而不是我们要返回的内容...
  • 明确一点,您知道 e.originalEvent 不是历史 API 的一部分吗?它是 jQuery 提供给原始事件数据的参考,而不是 jQuery 的事件对象。 e.originalEvent.state 是当前 popstate 事件的数据。
  • 是的,event.originalEvent 根本不提供“发件人”。
  • 同样的问题,表述更清​​楚:stackoverflow.com/questions/36525412/….

标签: javascript browser-history html5-history


【解决方案1】:

扩展历史对象

这是我的来源,你可以从https://gist.github.com/HasanDelibas/12050fc59d675181ea973d21f882081a看到完整的资源


这个库包含:

  • history.states -> 获取状态列表
  • history.stateIndex -> 当前状态索引
  • “historyChange”事件 -> 检测历史变化(from,to,side="back"|"forward")
  • 重要! state 必须是 history.pushState( **state**, ...) 的对象
(function(){
  let stateSymbol = "__state__index__";
  history.stateIndex =-1;
  history.states=[];
  let pushState = history.pushState;
  function add(data,title,url){
    if(data==null) data={};
    if(typeof data!="object") data={data:data};
    data[stateSymbol] = (history.stateIndex+1);
    history.states.splice(history.stateIndex+1,0,[data,title,url])
    history.states.splice(history.stateIndex+2)
    history.stateIndex++;
  }
  history.pushState =function(data,title,url=null){
    add(data,title,url);
    pushState.bind(history)(data,title,url);
  }
  addEventListener("popstate",function(e){
    var eventObject= {};
    var newStateIndex =  e.state!=null ? e.state[stateSymbol] : -1;
    eventObject.from = history.states[history.stateIndex];
    eventObject.to   = newStateIndex>-1 ? history.states[newStateIndex] : null;
    eventObject.side = history.stateIndex>newStateIndex ? "back" : "forward"; 
    if( newStateIndex > -1 && !(newStateIndex in history.states) ){
      add(history.state,"",window.location.href);
    }
    window.dispatchEvent(new CustomEvent("historyChange", {detail: eventObject} ))
    history.stateIndex = e.state!=null ? e.state[stateSymbol] : -1;
  });
})();

现在您可以使用history.states 对象获取所有状态, 并使用addEventListener("popstate",function(e))检测历史变化

使用

/**
  * @param e.detail.from [data,title,url]
  * @param e.detail.to   [data,title,url]
  * @param e.detail.side "back" | "forward"
  */
addEventListener("historyChange",function(e){
  var from = e.detail.from; // [ data , title , url ]
  var to   = e.detail.to;   // [ data , title , url ]
  var side = e.detail.side; // "back" | "forward"
  console.log( `You changed history. Side is ${e.detail.side}.\nFrom:${e.detail.from[2]}\nTo:${e.detail.to[2]}`)
})


history.pushState("1", "DENEME-TEST" ,"?1");
history.pushState("2", "DENEME-TEST" ,"?2");
// list of history states
console.log( history.states )
/*
[
  [ {...} ,  "DENEME-TEST" ,"?1" ]
  [ {...} ,  "DENEME-TEST" ,"?2" ]
]
*/
// get history current state index
console.log( history.stateIndex )
/*
1
*/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 2011-11-15
    • 2015-02-05
    • 1970-01-01
    相关资源
    最近更新 更多