1. 前端路由主要由两种方式实现

有一个路由表,以 path 为 key,value 是触发给 path 的回调函数。

  • location.hash + hashchange
  • history.pushState() + popState

1.1. location.hash, hashchange

说一下前端路由实现的简要原理,以 hash 形式(也可以使用 History API 来处理)为例,当 url 的 hash 发生变化时,触发 hashchange 注册的回调,回调中去进行不同的操作,进行不同的内容的展示。直接看代码或许更直观。

缺点:url 不好看,不利于 SEO

function Router() {
  this.routes = {};
  this.currentUrl = '';
}
Router.prototype.route = function(path, callback) {
  this.routes[path] = callback || function() {};
};
Router.prototype.refresh = function() {
  this.currentUrl = location.hash.slice(1) || '/';
  this.routes[this.currentUrl]();
};
Router.prototype.init = function() {
  window.addEventListener('load', this.refresh.bind(this), false);
  window.addEventListener('hashchange', this.refresh.bind(this), false);
};
window.Router = new Router();
window.Router.init();

上面路由系统 Router 对象实现,主要提供三个方法

  • init 监听浏览器 url hash 更新事件
  • route 存储路由更新时的回调到回调数组 routes 中,回调函数将负责对页面的更新
  • refresh 执行当前 url 对应的回调函数,更新页面

Router 调用方式以及呈现效果如下:点击触发 url 的 hash 改变,并对应地更新内容(这里为 body 背景色)

<ul>
    <li><a href="#/">turn white</a></li>
    <li><a href="#/blue">turn blue</a></li>
    <li><a href="#/green">turn green</a></li>
</ul>
var content = document.querySelector('body');
// change Page anything
function changeBgColor(color) {
  content.style.backgroundColor = color;
}
Router.route('/', function() {
  changeBgColor('white');
});
Router.route('/blue', function() {
  changeBgColor('blue');
});
Router.route('/green', function() {
  changeBgColor('green');
});

1.2. History Api: history.pushState() + popstate

  • history.pushState(data, title, url): 修改 url 的地址
  • history.replaceState(data, title, url)
  • popstate 事件: 监听地址的改变

手动的进行 pushState() 并不会触发 popstate 事件。点击浏览器前进后退时候触发。

<div id="div1">
  <ul>
    <li><a id="a1">s0</a></li>
    <li><a id="a2">k0</a></li>
  </ul>
</div>
var div1 = document.getElementById('div1');
var a1 = document.getElementById('a1');
var a2 = document.getElementById('a2');
var count1 = 0;
var count2 = 0;

history.replaceState({ count1: count1, count2: count2 }, null, ''); //最开始的状态,采用replace直接替换

a1.addEventListener('click', function() {
  count1++;
  history.pushState({ count1: count1, count2: count2 }, null, '#/s' + count1); //之后的状态,需要进行保存
  a1.innerHTML = 's' + count1;
});

a2.addEventListener('click', function() {
  count2++;
  history.pushState({ count1: count1, count2: count2 }, null, '#/k' + count2); //之后的状态,需要进行保存
  a2.innerHTML = 'k' + count2;
});

window.addEventListener('popstate', function(e) {
  console.log(e.state);
  a1.innerHTML = 's' + e.state.count1; //监听popstate事件,对状态进行还原
  a2.innerHTML = 'k' + e.state.count2;
});

1.2.1. reference

https://github.com/flatiron/director

Copyright © Guanghui Wang all right reserved,powered by GitbookFile Modified: 2019-08-25 13:56:34

results matching ""

    No results matching ""