大家用backbone、angular,可能都习惯了内置的路由,这两个框架的路由都是非常优秀的,强大而简单。

客户端(浏览器)路由原理其实比较简单,其实就是监听hash的变化。

在之前的架构探讨中,说到director.js这个路由类库不好使,那么,在这一篇,我们尝试自行实现一个简洁而且非常好使的路由类库。

原理先介绍,无非几个步骤:

  • 建立配置表(字符串路径和函数的映射)
  • 监听路由(onhashchange)
  • 处理路由变化,跟配置表的路径做匹配
    • 路径转化为正则表达式
    • 正则exec,匹配+抽取参数

其中难点就在于路径转化为正则表达式,director没做好就是这一步,而backbone则做得非常非常强大,那么我们可以尝试把backbone这一块代码抠出来。

路由表:

    var Route = root.Route = {
init: function (map) {
var defaultAction = map['*'];
if(defaultAction){
Route.defaultAction = defaultAction;
delete map['*'];
}
Route.routes = map;
init();
onchange();
},
routes: {},
defaultAction: null
};

监听路由变化:

    /**
* 这段判断,引用于director:https://github.com/flatiron/director
*/
function init(){
if ('onhashchange' in window && (document.documentMode === undefined
|| document.documentMode > 7)) {
// At least for now HTML5 history is available for 'modern' browsers only
if (this.history === true) {
// There is an old bug in Chrome that causes onpopstate to fire even
// upon initial page load. Since the handler is run manually in init(),
// this would cause Chrome to run it twise. Currently the only
// workaround seems to be to set the handler after the initial page load
// http://code.google.com/p/chromium/issues/detail?id=63040
setTimeout(function() {
window.onpopstate = onchange;
}, 500);
}
else {
window.onhashchange = onchange;
}
this.mode = 'modern';
} else {
throw new Error('sorry, your browser doesn\'t support route');
}
}

处理路由变化,先拼凑正则表达式:

    /**
* 引自backbone,非常牛逼的正则
* @param route
* @returns {RegExp}
*/
function getRegExp(route){
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
var splatParam = /\*\w+/g;
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
route = route.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, function(match, optional) {
return optional ? match : '([^/?]+)';
})
.replace(splatParam, '([^?]*?)');
return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
}

从原来的:module2/:name变成标准的正则表达式,个中奥妙大家自行顿悟

循环匹配:

    function onchange(onChangeEvent){
var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
var url = newURL.replace(/.*#/, '');
var found = false;
for (var path in Route.routes) {
var reg = getRegExp(path);
var result = reg.exec(url);
if(result && result[0] && result[0] != ''){
var handler = Route.routes[path];
handler && handler.apply(null, result.slice(1));
found = true;
}
}
if(!found && Route.defaultAction){
Route.defaultAction();
}
}

然后。。。做个简单的测试:

<script src="libs/backbone-route.js"></script>
<script> Route.init({
'module1': function(){
console.log(1);
},
'module2/:name/:age': function(){
console.log(2, arguments);
},
'module3(/:name)(/:age)': function(){
console.log('3', arguments);
},
'*': function(){
console.log(404);
}
});
</script>

本文代码:https://github.com/kenkozheng/HTML5_research/tree/master/backbone-route

一个类似backbone路由的纯净route ( 前端路由 客户端路由 backbone路由 )的更多相关文章

  1. socket 实现一个类似简单聊天室的功能(多客户端互相通信)

    server端: #coding=utf-8 ''' 一个广播程序,linux运行 ''' import select,socket import traceback def broadcast(co ...

  2. vue+axios 前端实现登录拦截(路由拦截、http拦截)

    一.路由拦截 登录拦截逻辑 第一步:路由拦截 首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录.如果用户已经登录,则顺利进入路由, 否则就进入登录 ...

  3. 【转】vue+axios 前端实现登录拦截(路由拦截、http拦截)

    一.路由拦截 登录拦截逻辑 第一步:路由拦截 首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录.如果用户已经登录,则顺利进入路由, 否则就进入登录 ...

  4. Angular入门到精通系列教程(13)- 路由守卫(Route Guards)

    1. 摘要 2. 路由守卫(Route Guards) 2.1. 创建路由守卫 2.2. 控制路由是否可以激活 2.3. 控制路由是否退出(离开) 3. 总结 环境: Angular CLI: 11. ...

  5. Web Api通过Route、RoutePrefix等特性设置路由

    [Route("customers/{customerId}/orders")] [HttpGet] public IEnumerable<Order> FindOrd ...

  6. 每天一个Linux命令(47)route命令

        Linux系统的route命令用于显示和操作内核IP路由表(show / manipulate the IP routing table).     (1)用法:     用法:  route ...

  7. react 中的路由 Link 和Route和NavLink

    route是配置,link是使用 https://blog.csdn.net/chern1992/article/details/77186118(copy) 嵌套路由一般使用Route,类似于vue ...

  8. 路由配置(route IP

    转载于:http://blog.csdn.net/chenlycly/article/details/52141854 使用下面的 route 命令可以查看 Linux 内核路由表. # route ...

  9. 路由信息相关 route 网卡

    目录 route命令 1.查看路由表 2.管理路由 基本网络配置 添加网卡地址 修改网卡UUID route命令 路由表管理命令,路由表主要构成: Destination: 目标网络ID,表示可以到达 ...

随机推荐

  1. Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead. Please use Android Tools>Fix project Properties.

    重装操作系统之后,或者破坏了Android的开发环境之后,需要重新配置好Android的开发环境.但是配置好后,导入原有的项目时,报错: Android requires compiler compl ...

  2. Pure – 赞!轻量的、响应式的 CSS 模块集

    Pure 是一组轻量的,响应式的 CSS 模块,您可以使用在任何的 Web 项目中.充分考虑了移动设备中的使用,保持文件体积尽量小,每行 CSS 都进行了仔细的考虑. Pure 基于 Normaliz ...

  3. JavaScript 回忆录

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 1. 基本类型和应用类型 1.1 复制变量值的不同 值类型的变量在复制变量值后互不影响,因为值类型本身保存的就是 ...

  4. .Net常见错误

    常见错误 #1: 把引用当做值来用,或者反过来 C++ 和其他很多语言的程序员,习惯了给变量赋值的时候,要么赋单纯的值,要么是现有对象的引用.然而,在C# 中,是值还是引用,是由写这个对象的程序员决定 ...

  5. 创建支持多种屏幕尺寸的Android应用

    Android涉及各种各样的支持不同屏幕尺寸和密度的设备.对于应用程序,Android系统通过设备和句柄提供了统一的开发环境,大部分工作是校正每一个应用程序的用户界面到它显示的屏上.与此同时,系统提供 ...

  6. nginx+uwsgi+django+celery+supervisord环境部署

    前言 很久没更博客了,最近新写了一个小项目,后边有时间把一些心得放上来,先把环境的部署方式整理出来. 部署过程 先将环境的python升级为2.7 保证有pip 安装了nginx并配置 vim /Da ...

  7. 大话immutable.js

    为啥要用immutable.js呢.毫不夸张的说.有了immutable.js(当然也有其他实现库)..才能将react的性能发挥到极致!要是各位看官用过一段时间的react,而没有用immutabl ...

  8. 【转】sql server 获取每一个类别中值最大的一条数据

    /* 数据如下: name val memo a 2 a2(a的第二个值) a 1 a1--a的第一个值 a 3 a3:a的第三个值 b 1 b1--b的第一个值 b 3 b3:b的第三个值 b 2 ...

  9. 打开IE错误解决方法

    1. 502.1 Internal Server Error Handle svc-Integraged has a bad module ManagedPipelineHandle解决方法:此种情况 ...

  10. ASP.Net中防止页面刷新重复提交的几种方法

    [摘要] 目前很多网站都要提交页面插入或更新数据库,比如留言本,一个用户提交留言后,如果按F5,就会重新提交一遍留言,导致数据库出现两条一模一样的留言,本文介绍了几种防止页面刷新,导致重复提交数据的方 ...