一、路由跳转了解
前端路由跳转是一种在不重新加载页面的情况下,通过改变URL来切换时图的技术。它允许开发人员在不向服务器发送请求的情况下,通过修改URL来改变页面的显示内容,从而实现单页面应用(SPA)的效果。前端路由机制使得SPA能够模拟多页面应用的效果,提高了用户体验和应用的相应速度。
二、前端路由跳转基本原理
1、目前前端流行的框架里都推介单页面应用SPA开发模式,在路由切换时替换DOM Tree中最小修改的部分DOM,来减少原先因为多页面应用的页面跳转带来的巨量性能损耗。它们都有各自典型路由解决方案,@angular/route、react- route,@react-navigation/native等。
2、一般来说,这些路由插件总是提供两种不同方式的路由方式:Hash模式和History模式,有时也会提供非浏览器环境下的路由方式Abstract,在vue-route中时使用了外观模式将几种不同的路由方式提供了一个一致的高层借口,让我们可以更解耦的再不同路由方式中切换。
3、Hash模式和History模式除了外观上的不同之处,还一个区别是:Hash模式的状态保存需要另外传递,而HTML5 History原生提供了自定义状态传递的能力,我们可以直接利用其来传递信息。
三、Hash模式
1、Hash原理
Hash模式通过URL中的hash(#)来实现路由。当URL的#后面发生变化时,浏览器不会像服务器发送请求,而是触发hashchange事件,从而实现页面的跳转和数据加载。
HTML页面中通过锚点定位原理课进行无刷新跳转,触发后URL地址中会多出# + ‘XXX’的部分,同时在全局的window对象上触发hashchange事件,这样在页面锚点哈希改变为某个预设值的时候,通过代码触发对应页面DOM变化,就可以实现基本的路由了。由于hash值变化不会导致浏览器向服务器发出请求,而且hash改变会触发hashchange事件,浏览器的进后退也能对其进行控制,所以人们在HTML5的history出现之前,基本都是使用hash来实现前端路由的。
2、hash相关的API
location.href():返回完成的URL;
location.hash():返回URL的锚部分;
location.pathname():返回URL路径名;
hashchange事件:当location.hash发生改变时,将触发这个事件
四、History模式
1、history模式原理
history模式利用HTML5中的History API(pushState、replaceState和popstate)来实现URL跳转而无需重新加载页面。通过调用History API,可以修改浏览器历史记录中的URL,并且不像hash模式那样会在URL中出现#。现代的前端框架,如React Route v4、Vue Route等,都是用history模式作为默认的实现方式。
2、history模式相关的API
history.go(n):路由跳转,比如n为2时往前移动2个页面,n为-2时向后移动2个页面,n为0是刷新当前页面
history.back():路由后退,相当于history.go(-1)
history.forward():路由前进,相当于history.go(1)
history.pushState():添加一条路由历史记录
history.replaceState():替换当前页面在路由历史记录的信息
popstate事件:当活动的历史记录发生变化,就会触发popstate事件,在点击浏览器的前进后退按钮或着调用上面前三个方法的时候也会触发
五、如何监听两种路由模式的变化
对于hash模式,可以监听hashchange事件来捕获到hash的改变,从而实现前端路由
对于history模式,我们可以监听popstate事件来监听forward,back,go方法触发的路由变化,对于History.pushState()和History.replaceState(),一种方法是重写两个方法,在方法里面主动触发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');
然后全局监听两个方法
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行为。