前端路由实现原理

来源:互联网 发布:java调用jquery 编辑:程序博客网 时间:2024/05/16 02:00

场景

分别点击顶部的”推荐”、”书城”、”书架”进而在顶部下面展示不同的页面。点击其中1个隐藏其他页面。

实现原理

点击a标签对应的”推荐”、”书城”、”书架”,改变hash值后,监听onpopstate事件,进而进行不同的操作。

代码实现

1. 利用H5router实现整个路由系统。

function H5router() {    this.routers = {};    this.init();}

2. 应用场景

let h5route = new H5router();h5route.route('/recommend', () => {    h5route.hideOther();});h5route.route('/bookcity', () => {    h5route.hideOther();});h5route.route('/bookshelves', () => {    h5route.hideOther();});

3. 将路由和对应的回调关联

h5route.route方法就是将回调函数和路径添加到H5router构造函数内部的this.routers中。如下:

 h5route.rototype.route = function (url, cb) {        let newurl = url || '';        this.routers[newurl] = cb || function () {}; }

4. 监听popstate事件

h5route.rototype.init作用就是监听popstate事件,进而执行h5route原型上的refresh方法。这里监听onhashchange也可以。

 h5route.rototype.init = function () {        window.addEventListener('popstate', this.refresh.bind(this));    },

5. 执行路由对应的回调

这里的回调指的是2中() => { h5route.hideOther(); }

h5route.rototype.refresh = function () {        let hash = location.hash.substr(1) || '/';        this.routers[hash]();    },

所有代码

function H5router() {    this.routers = {        '/': function () {}    };    this.init();}H5router.prototype = {    route: function (url, cb) {        let newurl = url || '';        this.routers[newurl] = cb || function () {};    },    init: function () {        window.addEventListener('popstate', this.refresh.bind(this));    },    refresh: function () {        let hash = location.hash.substr(1) || '/';        this.routers[hash]();    },    hideOther: function () {        let head = document.getElementsByClassName('head')[0];        let content = document.getElementsByClassName('content')[0];        let className = location.hash.substr(2) || '/';        Array.from(content.children).forEach(function (ele) {            if (ele.className.indexOf(className) === -1) {                ele.style.display = 'none';            } else {                ele.style.display = 'block';            }        });    }};let h5route = new H5router();h5route.route('/recommend', () => {    h5route.hideOther();});h5route.route('/bookcity', () => {    h5route.hideOther();});h5route.route('/bookshelves', () => {    h5route.hideOther();});

HTML部分:

 <ul class="head">        <li class="head-list"><a id="list-recommend" class="head-list-go" href="#/recommend">推荐</a></li>        <li class="head-list"><a id="list-bookcity" class="head-list-go " href="#/bookcity">书城</a></li>        <li class="head-list"><a id="list-bookshelves" class="head-list-go " href="#/bookshelves">书架</a></li>    </ul>

总结

H5的新API history.pushState()和history.changeState()方法相当于改变history历史记录中的信息,在点击回退或者前进按钮时添加或者替换之前缓存的页面,因此这两个API不能触发onpopstate事件,即从浏览器的历史记录中将某条记录弹出的事件,只有前进和后退按钮可以,这两个API为前进和后退按钮提供了更加灵活的应用。
只要hash值改变就会触发onpopstateonhashchange事件。