在单页运用中,怎样文雅的监听url的变化

  单页运用的道理从夙兴的依据url的hash变化,到依据H5的history的变化,完成无革新条件下的页面从新衬着。那末在单页运用中是怎样监听url的变化呢,本文将总结一下,怎样在单页页面中文雅的监听url的变化。

  • 单页运用道理
  • 监听url中的hash变化
  • 监听经由过程history来转变url的事宜
  • replaceState和pushState行动的监听

原文在我的博客中:https://github.com/forthealll…

迎接star

一、单页运用道理

  单页运用的道理,在我们的上一篇文章中React-Router源码浏览已讲的很细致,这里做一个简朴引见。单页运用使得页面可以在无革新的条件下从新衬着,经由过程hash或许html5 Bom对象中的history可以做到转变url,然则不革新页面。

(1)经由过程hash来完成单页路由

  初期的前端路由是经由过程hash来完成的:

  转变url的hash值是不会革新页面的。

  因而可以经由过程hash来完成前端路由,从而完成无革新的结果。hash属性位于location对象中,在当前页面中,可以经由过程:

window.location.hash='edit'

来完成转变当前url的hash值。实行上述的hash赋值后,页面的url发作转变。

赋值前:http://localhost:3000
赋值后:http://localhost:3000/#edit

在url中多了以#末端的hash值,然则赋值前后虽然页面的hash值转变致使页面完全的url发作了转变,然则页面是不会革新的。

另外,除了可以经由过程window.location.hash来转变当前页面的hash值外,还可以经由过程html的a标签来完成:

<a href="#edit">edit</a>

(2)经由过程history完成前端路由

  HTML5的History接口,History对象是一个底层接口,不继续于任何的接口。History接口许可我们操纵浏览器会话汗青纪录。

History供应了一些属性和要领。

History的属性:

  • History.length: 返回在会话汗青中有若干条纪录,包括了当前会话页面。另外假如翻开一个新的Tab,那末这个length的值为1
  • History.state:

保留了会动身popState事宜的要领,所传递过来的属性对象(背面会在pushState和replaceState要领中细致的引见)

History要领:

  • History.back(): 返回浏览器会话汗青中的上一页,跟浏览器的回退按钮功用雷同
  • History.forward():指向浏览器会话汗青中的下一页,跟浏览器的行进按钮雷同
  • History.go(): 可以跳转到浏览器会话汗青中的指定的某一个纪录页
  • History.pushState():pushState可以将给定的数据压入到浏览器会话汗青栈中,该要领吸收3个参数,对象,title和一串url。pushState后会转变当前页面url,然则不会伴随着革新
  • History.replaceState():replaceState将当前的会话页面的url替代成指定的数据,replaceState后也会转变当前页面的url,然则也不会革新页面。

上面的要领中,pushState和repalce的雷同点:

就是都邑转变当前页面显现的url,但都不会革新页面。

差别点:

pushState是压入浏览器的会话汗青栈中,会使得History.length加1,而replaceState是替代当前的这条会话汗青,因而不会增添History.length.

(3)总结

  经由过程转变hash值,或许history的repalceState和pushState都可以完成无革新的转变url。如许还留有一个题目须要处理:

  怎样监听url的转变

  由于我们不仅要无革新的转变url,还要监听到这个url转变的行动,依据该行动去从新衬着视图。鄙人几章中,重点引见一下怎样监听url的转变。

二、监听url中的hash变化

  经由过程hash转变了url,会触发hashchange事宜,只需监听hashchange事宜,就可以捕获到经由过程hash转变url的行动。

window.onhashchange=function(event){
  console.log(event);
}
//或许
window.addEventListener('hashchange',function(event){
   console.log(event);
})

当hash值转变时,输出一个HashChangeEvent。该HashChangeEvent的详细值为:

{isTrusted: true, oldURL: "http://localhost:3000/", newURL:   "http://localhost:3000/#teg", type: "hashchange".....}

有了监听事宜,且转变hash页面不革新,如许我们就可以够在监听事宜的回调函数中,实行我们展现和隐蔽差别UI显现的功用,从而完成前端路由。

三、监听经由过程history来转变url的事宜

在上一章讲到了经由过程History转变url有以下几种要领:History.back()、History.forward()、History.go()、History.pushState()和History.replaceState()。

同时在history中还支撑一个事宜,该事宜为popstate。第一主意就是假如popstate可以监听一切的history要领所致使的url变化,那末就功德圆满了。遗憾的是:

History.back()、History.forward()、History.go()事宜是会触发popstate事宜的,然则History.pushState()和History.replaceState()不会触发popstate事宜。

假如是History.back(),History.forward()、History.go()那末会触发popstate事宜,我们只须要:

window.addEventListener('popstate', function(event) {
     console.log(event);
})

就可以够监听到响应的行动,手动挪用:

window.history.go();
window.history.back();
window.history.forward();

都邑触发这个事宜,另外,在浏览器中点击退却和行进按钮也会触发popstate事宜,这个事宜内容为:

PopStateEvent {isTrusted: true, state: null, type: "popstate", target: Window, currentTarget: Window, …}

然则,History.pushState()和History.replaceState()不会触发popstate事宜,举例来说:

window.addEventListener('popstate', function(event) {
     console.log(event);
})
window.history.pushState({first:'first'}, "page 2", "/first"})

上述例子中不会有任何的输出,由于并没有监听的popstate事宜的发作。

然则History.go和History.back()等,虽然可以触发popstate事宜,然则都邑革新页面,我们在单页运用中运用的是replaceState和pushState,因而这里另有一个守候处理的题目:

怎样监听replaceState和pushState行动

四、replaceState和pushState行动的监听

  在上面的例子中我们发明History.replaceState和pushState确切不会触发popstate事宜,那末怎样监听这两个行动呢。可以经由过程在要领内里主动的去触发popState事宜。另一种就是在要领中建立一个新的全局事宜。

详细做法为:

var _wr = function(type) {
   var orig = history[type];
   return function() {
       var rv = orig.apply(this, arguments);
      var e = new Event(type);
       e.arguments = arguments;
       window.dispatchEvent(e);
       return rv;
   };
};
 history.pushState = _wr('pushState');
 history.replaceState = _wr('replaceState');

如许就建立了2个全新的事宜,事宜名为pushState和replaceState,我们就可以够在全局监听:

window.addEventListener('replaceState', function(e) {
  console.log('THEY DID IT AGAIN! replaceState 111111');
});
window.addEventListener('pushState', function(e) {
  console.log('THEY DID IT AGAIN! pushState 2222222');
});

如许就可以够监听到pushState和replaceState行动。

参考文章:https://stackoverflow.com/que…

    原文作者:yuxiaoliang
    原文地址: https://segmentfault.com/a/1190000017560688
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞