[关闭]
@xudongh 2017-05-14T23:48:39.000000Z 字数 2803 阅读 2088

前端路由的简单思路

前端开发


前端路由

在以往的web开发中,浏览器每发出一个请求,都会传输到服务器进行处理,然后返回响应结果。
而对于使用了前端路由的页面,我们可以由浏览器预处理一些事件,当浏览器读取到一个注册到前端路由中的URL请求时,就可以直接在浏览器端响应,而不用交由服务器进行处理。前端路由被应用于spa(single page web application)页面,即单页web应用。
举个例子,有一个单页应用,URL地址为http://www.my-first-spa.com,页面上有个超链接为http://www.my-first-spa.com/page-1的事件,当我们触发这个事件时,页面不会跳转然后转到这个新的页面,而是让在这个页面进行实时更新。
所以,前端路由就是把不同的页面或者内容交给前端来进行处理,在点击浏览另一个页面时,整个页面并不会闪烁一样的刷新,在更新页面数据时,相应地改变地址栏中的url。

实现前端路由

由于ajax异步请求技术的诞生,我们可以实现局部更新页面的功能,但其ajax会涉及到这些问题:

  1. 可以无刷新改变页面内容,但无法改变页面URL
  2. 不能保存URL地址进行再访问相应的内容
  3. 不能很好的处理浏览器的前进、后退等问题
  4. 对搜索引擎的SEO优化不友好

为了实现既能在不刷新页面的情况更新页面数据,又能相应地更新URL地址,需要用到ajax + html5的两个api。

实现前端路由需要用到html5中的两个API:

这两个方法允许我们访问并操作浏览器的历史浏览记录条目。pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录,两者传入的参数相同:

  1. history.pushState(state object,title,URL);
  2. history.replaceState(state object,title,URL);

对于第三个参数URL,可传入绝对路径,也可传入相对路径,以百度首页为例,https://www.baidu.com,打开该页面,在控制台中输入:

  1. window.history.pushState(null, null, "https://www.baidu.com?id=123");
  2. //url变化:https://www.baidu.com?id=123
  3. window.history.pushState(null, null, "https://www.baidu.com/id/123");
  4. //url变化:https://www.baidu.com/id/123
  5. window.history.pushState(null, null, "?id=123");
  6. //url变化:https://www.baidu.com?id=123
  7. window.history.pushState(null, null, "id=123");
  8. //url变化:http://www.baidu.com/id=123
  9. window.history.pushState(null, null, "/id/123");
  10. //url变化:https://www.baidu.com/id/123
  11. //错误
  12. window.history.pushState(null, null, "http://www.baidu.com?id=123");

打开浏览器的历史记录,可以看出产生几条新的历史访问记录。
image_1bf4l5u4nequic16so137k1egk9.png-26.8kB

但可以看到上面例子的最后一个举例,代码运行出错,这是因为这两个方法都不能跨域访问。

上面是我们所需要用到的比较基本的api。代码方面,前端路由实现的基本原理在于,通过使用hashchange事件的监听,监测url地址的变化,如果url地址发生变化,则执行响应的操作。

  1. function Router() {
  2. this.cache = {};
  3. this.curUrl = '';
  4. this.router = function(path, callback) {
  5. this.cache[path] = callback || function() {};
  6. }
  7. this.refresh = function() {
  8. this.curUrl = location.hash.slice(1) || '/';
  9. this.cache[this.curUrl]();
  10. }
  11. this.init = function() {
  12. window.addEventListener('load', this.refresh.bind(this), false);
  13. window.addEventListener('hashchange', this.refresh.bind(this), false);
  14. }
  15. }

在上述Router对象中,一共提供了三个方法:

,为了初始化路由,需要调用Router对象:

  1. var R = new Router();
  2. R.init();
  3. var res = document.getElementById('result');
  4. R.router('/', function() {
  5. res.style.background = '#ababab';
  6. res.innerHTML = '现在颜色为默认';
  7. });
  8. R.router('/blue', function() {
  9. res.style.background = '#1497fe';
  10. res.innerHTML = '现在颜色为blue';
  11. });
  12. R.router('/red', function() {
  13. res.style.background = '#ff5252';
  14. res.innerHTML = '现在颜色为red';
  15. });
  16. R.router('/yellow', function() {
  17. res.style.background = '#ffea94';
  18. res.innerHTML = '现在颜色为yellow';
  19. });

加上html和css代码,实现了一个更换颜色,同时会自动更新url地址的页面,例子如下:
https://codepen.io/danielxu/pen/OmQzeJ

image_1bfp0lbpns5la7p1jvvqq5bmu9.png-15.1kB

这就是一个简单路由的实现。

总结

在上面例子中,显然是非常简单的,但实际上路由并不是这么简单,因为要实时获取数据,那就需要ajax异步请求页面数据;同时为了满足大量url,需要对url的hash进行正则匹配处理。当然,虽然例子简单,但其前端路由的基本思路正是如此。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注