前端路由

一、什么是前端路由

在web开发的过程中,路由的使用是必不可少的,这里的路由不是指我们日常生活中的路由器,但是实现原理基本相同,它代表一个url与相应处理程序的影射关系,用户在输入要访问的url之后,路由会解析url中的路径,之后根据映射表中的映射关系查找相应的预设函数,并将结果返回给用户,以此完成一次操作。

前端路由它是通过一个hash函数或者H5提供的history API来实现。在进行开发时,路由用来设定访问路径,并将路径与相应的组件映射起来,用户在访问相应的路径时,路由根据映射关系实现不同组件间的切换,整个过程都是在同一个页面中实现,不涉及页面间的跳转,也就是我们常说的SPA(single page application)单页应用。

二、前端路由的优势

  1. 页面刷新速度快。由于后端路由在请求一个新路径时,会重新向服务器发送请求,之后再根据服务器的相应结果重新渲染页面,这个过程会受到网络延迟的影响,而前端路由省略了整个请求过程,只是完成部分组件间的切换,因此页面的刷新速度会相对较快,用户体验相对较好。
  2. 页面状态可记录。在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题

三、前端路由的实现方法

   目前前端路由的实现方法主要有两种方法,location.hash和window.history。

   1.location.hash实现前端路由

hash就是一个url中#后面的部分,也叫做url的锚部分,这个 # 有两种情况,第一种是我们所谓的锚点,比如页面目录跳转。第二种就是路由里面的#,我们称之为hash,通过hash方法实现前端路由主要是用到的是onhashchange事件,这个事件可以实时监听url中hash值的变化,由此来根据hash值的变化进行一些DOM的切换操作。

  • onhashchange事件

window.onhashchange = func;



window.addEventListener("hashchange", func, false);

了解了hash的基本原理后,我们再来看下如何用它实现路由:

设计思路:

当浏览器地址栏url的hash值发生变化时,就会触发onhashchange事件,这时通过window.location.hash可以拿到当前浏览器的url的hash值,注意此时的hash值是带有#的,因此需要对其值进行相应的处理,去掉#,并且如果当前url不含hash值的话,就将其当做根目录处理。之后将url和相应的组件函数进行映射,根据不同的hash值执行不同的回调函数,也就是加载相应的组件。

代码如下:

(function () {
    function Router() {
        this.routes = {};//用来保存路由
        this.curentUrl = ''; //获取当前的hash
    }
    // 在Router.prototype原型上设置方法,第一个设置路由,第二个路由跳转,第三个页面初始化

    Router.prototype.route = function (path, callback) {
        //保存路由对应的函数,创建url和组件的映射关系
        this.routes[path] = callback;
        // console.log( this.routes );
    }
    Router.prototype.reloadPage = function () {
        this.curentUrl = location.hash.substring(1) || '/index'; //获取hash值,并截取#后的内容
        this.routes[this.curentUrl](); //根据路由名 执行对应的函数
    }
    Router.prototype.init = function () { //监听路由变化
        // 当页面完全加载后触发事件
        window.addEventListener('load', this.reloadPage.bind(this));
        // hash变化触发事件
        window.addEventListener('hashchange', this.reloadPage.bind(this));
    }
    window.Router = Router;
})();
// 指定容器渲染组件
function display_page(url) {
    $("#router").load(url)
}
// 创建实例并初始化
var oRouter = new Router();
oRouter.init();
// 创建映射关系
oRouter.route('/index', function () {
    display_page('./page/main.html');
});
oRouter.route('/news', function () {
    display_page('./page/news.html');
});
oRouter.route('/about', function () {
    display_page('./page/about.html');
});

   2.window.history和popstate实现前端路由

相关API:

window.history.pushState(state, title, url) 
// state:需要保存的数据,这个数据在触发popstate事件时,可以在event.state里获取
// title:标题,基本没用,一般传 null
// url:设定新的历史记录的 url。新的 url 与当前 url 的 origin 必须是一樣的,否则会抛出错误。url可以是绝对路径,也可以是相对路径。
//如 当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, './qq/'),则变成 https://www.baidu.com/a/qq/,
//执行history.pushState(null, null, '/qq/'),则变成 https://www.baidu.com/qq/

window.history.replaceState(state, title, url)
// 与 pushState 基本相同,但她是修改当前历史记录,而 pushState 是创建新的历史记录

window.addEventListener("popstate", function() {
    // 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发              
});

window.history.back() // 后退
window.history.forward() // 前进
window.history.go(1) // 前进一步,-2为后退两步,window.history.lengthk可以查看当前历史堆栈中页面的数量

设计思路:

当想要跳转到指定url的时候,将目标url通过pushState()或者replaceState()方法填入到history和地址栏中,此时由于上述两种方法不会主动进行页面刷新,因此页面仍停留在当前页面,只是url地址发生了改变。之后通过popstate事件响应,执行相应的回调函数,实现前端组件间的切换。

代码如下:

(function () {
        var url = 'nav1';

        history.replaceState(url,null,'');//最开始的状态,采用replace直接替换
        $('#router').html('

'+url+'

'); $('a').on('click', function () { console.log(this.text) url = this.text; $('#router').html('

' + url + '

') history.pushState(url, null, '#/' + url); }) window.addEventListener('popstate', function (e) { console.log(e.state); url = e.state $('#router').html('

' + url + '

') }); window.addEventListener('load', function () { url = location.hash.slice(2) || 'nav1'; history.replaceState(url, null, ''); console.log(location.hash); $('#router').html('

' + url + '

'); }); })()

 

你可能感兴趣的:(js,html,前端路由)