history的pushState和replaceState

pushState和replaceState

HTML5新接口,可以改变网址(存在跨域限制)而不刷新页面,这个强大的特性后来用到了单页面应用如:vue-router,react-router-dom中。
注意:仅改变网址,网页不会真的跳转,也不会获取到新的内容,本质上网页还停留在原页面!

window.history.pushState(state, title, targetURL);
@状态对象:传给目标路由的信息,可为空
@页面标题:目前所有浏览器都不支持,填空字符串即可
@可选url:目标url,不会检查url是否存在,且不能跨域。如不传该项,即给当前url添加data
window.history.replaceState(state, title, targetURL);
@类似于pushState,但是会直接替换掉当前url,而不会在history中留下记录

popstate事件

popstate事件会在点击后退、前进按钮(或调用history.back()history.forward()history.go()方法)时触发。前提是不能真的发生了页面跳转,而是在由history.pushState()或者history.replaceState()形成的历史节点中前进后退
注意:用history.pushState()或者history.replaceState()不会触发popstate事件。

window.onpopstate = function(event) {
  console.log(event.state);
  console.log(window.history.state);
};

以上两种方式皆可获取之前在pushStatereplaceState中传入的state


监听pushState和replaceState

由于history.pushState()或者history.replaceState()不会触发popstate,需要自己设法进行监听。

  • 重写pushState,先驱动自定义回调函数/事件,再调用原生的pushState
(function (history) {
  var pushState = history.pushState;
  history.pushState = function (state) {
    if (typeof history.onpushstate == "function") {
      history.onpushstate({ state: state });
    }
    return pushState.apply(history, arguments);
  };
})(window.history);
history.onpushstate = function (e) {
  console.log('pushed', e);//e即state
}

const state = { 'page_id': 1 }
const title = ''
const url = 'hello.html'
history.pushState(state, title, url);
var _wr = function(type) {
  var orig = history[type];
  return function() {
    var e = new Event(type);
    e.arguments = arguments;
    window.dispatchEvent(e);
    var rv = orig.apply(this, arguments);
    return rv;
  };
};
history.pushState = _wr('pushState');
history.replaceState = _wr('replaceState');
window.addEventListener('pushState', function(e) {
  var path = e && e.arguments.length > 2 && e.arguments[2];
  var url = /^http/.test(path) ? path : (location.protocol + '//' + location.host + path);
  console.log('old:'+location.href,'new:'+url);
});
window.addEventListener('replaceState', function(e) {
  var path = e && e.arguments.length > 2 && e.arguments[2];
  var url = /^http/.test(path) ? path : (location.protocol + '//' + location.host + path);
  console.log('old:'+location.href,'new:'+url);
});

你可能感兴趣的:(history的pushState和replaceState)