js中的路由匹配
routie插件:http://projects.jga.me/routie/
/**
* 路由
* @example
* routie(
* {
* '/':function(){ },
* '/main':function (){ }, //
* '/list/:id': function(id){ //带参数的路由
loadModule("#maindiv","list",{"id":id})
* }
* }
* )
*/
(function(w) { var routes = [];
var map = {};
var reference = "routie";
var oldReference = w[reference]; var Route = function(path, name) {
this.name = name;
this.path = path;
this.keys = [];
this.fns = [];
this.params = {};
this.regex = pathToRegexp(this.path, this.keys, false, false); }; Route.prototype.addHandler = function(fn) {
this.fns.push(fn);
}; Route.prototype.removeHandler = function(fn) {
for (var i = 0, c = this.fns.length; i < c; i++) {
var f = this.fns[i];
if (fn == f) {
this.fns.splice(i, 1);
return;
}
}
};
//执行匹配的路由对应的回调函数
Route.prototype.run = function(params) {
for (var i = 0, c = this.fns.length; i < c; i++) {
this.fns[i].apply(this, params);
}
}; Route.prototype.match = function(path, params){
var m = this.regex.exec(path); if (!m) return false; for (var i = 1, len = m.length; i < len; ++i) {
var key = this.keys[i - 1]; var val = ('string' == typeof m[i]) ? decodeURIComponent(m[i]) : m[i]; if (key) {
this.params[key.name] = val;
}
params.push(val);
} return true;
}; Route.prototype.toURL = function(params) {
var path = this.path;
for (var param in params) {
path = path.replace('/:'+param, '/'+params[param]);
}
path = path.replace(/\/:.*\?/g, '/').replace(/\?/g, '');
if (path.indexOf(':') != -1) {
throw new Error('missing parameters for url: '+path);
}
return path;
}; var pathToRegexp = function(path, keys, sensitive, strict) {
if (path instanceof RegExp) return path;
if (path instanceof Array) path = '(' + path.join('|') + ')';
path = path
.concat(strict ? '' : '/?')
.replace(/\/\(/g, '(?:/')
.replace(/\+/g, '__plus__')
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
keys.push({ name: key, optional: !! optional });
slash = slash || '';
return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || '');
})
.replace(/([\/.])/g, '\\$1')
.replace(/__plus__/g, '(.+)')
.replace(/\*/g, '(.*)');
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
}; var addHandler = function(path, fn) {
var s = path.split(' ');
var name = (s.length == 2) ? s[0] : null;
path = (s.length == 2) ? s[1] : s[0]; if (!map[path]) {
map[path] = new Route(path, name);
routes.push(map[path]);
}
map[path].addHandler(fn);
}; //调用入口
var routie = function(path, fn) {
if (typeof fn == 'function') {
addHandler(path, fn);
routie.reload();
} else if (typeof path == 'object') { //多个路由的情况 {'/list':function(){},}
for (var p in path) {
addHandler(p, path[p]); //将每个路由通过Route实例化,生成路由对象
}
routie.reload(); //获取当前url中的hash,找到匹配的路由,并执行路由的回调函数
} else if (typeof fn === 'undefined') {
routie.navigate(path);
}
}; routie.lookup = function(name, obj) {
for (var i = 0, c = routes.length; i < c; i++) {
var route = routes[i];
if (route.name == name) {
return route.toURL(obj);
}
}
}; routie.remove = function(path, fn) {
var route = map[path];
if (!route)
return;
route.removeHandler(fn);
}; routie.removeAll = function() {
map = {};
routes = [];
}; routie.navigate = function(path, options) {
options = options || {};
var silent = options.silent || false; if (silent) {
removeListener();
}
setTimeout(function() {
window.location.hash = path; if (silent) {
setTimeout(function() {
addListener();
}, 1);
} }, 1);
}; routie.noConflict = function() {
w[reference] = oldReference;
return routie;
}; var getHash = function () {
var result = window.location.hash.substring(1);
if (result.indexOf("&")>-1) {
result = window.location.hash.substring(1, window.location.hash.indexOf("&"));
} else if (result.indexOf("?") > -1) {
result = window.location.hash.substring(1, window.location.hash.indexOf("?"));
}
return result;
}; var checkRoute = function(hash, route) {
var params = [];
if (route.match(hash, params)) {
route.run(params);
return true;
}
return false;
}; var hashChanged = routie.reload = function() {
var hash = getHash();
for (var i = 0, c = routes.length; i < c; i++) {
var route = routes[i];
if (checkRoute(hash, route)) {
return;
}
}
}; var addListener = function() {
if (w.addEventListener) {
w.addEventListener('hashchange', hashChanged, false);
} else {
w.attachEvent('onhashchange', hashChanged);
}
}; var removeListener = function() {
if (w.removeEventListener) {
w.removeEventListener('hashchange', hashChanged);
} else {
w.detachEvent('onhashchange', hashChanged);
}
};
addListener(); w[reference] = routie; })(window);
js中的路由匹配的更多相关文章
- vue.js中的路由vue-router2.0使用
在我们平时工作中,我们有时候会有需求,按照不同的规则,加载不同的组件,页面不去跳转,常见的操作是ajax的异步操作,实现局部刷新加载新数据 在vue中,我们写了很多不同的组件,这时候,实现不刷新调用新 ...
- Angular JS中的路由
前 言 本章节将为大家介绍 AngularJS 路由.AngularJS 路由允许我们通过不同的 URL 访问不同的内容.通过 AngularJS 可以实现多视图的单页We ...
- djanjo中url路由匹配规则是啥意思
一,django路由匹配规则的本质是通过正则表达式对用户的url进行匹配. 1,r 是正则表达式中防止转义的符号,例如在python/n代表换行,加上r就不换行了. 2,$ 正则表达式中表示以什么什么 ...
- Go的http包中默认路由匹配规则
# 一.执行流程 首先我们构建一个简单http server: ```go package main import ( "log" "net/http" ) f ...
- node.js中的路由(url)初步
1.建立n4_root.js var http = require('http'); var url = require('url'); //这是node.js中自带的var router = req ...
- node.js中使用路由方法
1.数组的find方法还是不会用,改为filter 2.正规表达式还是理解的不好 //var myrouter = require("./myrouter"); //myroute ...
- ASP.NET Core 中的SEO优化(3):自定义路由匹配和生成
前言 前两篇文章主要总结了CMS系统两个技术点在ASP.NET Core中的应用: <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET ...
- Vue 项目中对路由文件进行拆分(解构的方法)
项目需求场景: 在开发项目过程中,在项目过于庞大,路由信息非常多的情况下,如果将路由配置信息都放在一个文件里面,那么这个JS是不方便维护的, 那么,这个时候需要我们把这个庞大的路由文件,根据项目功能分 ...
- VS2013和VS2015中MVC 区域路由匹配顺序相反
创建测试工程 分别在vs2013和vs2015中创建mvc项目,并创建First.Second.Three三个Area,每个Area下面创建一个HomeController和Index视图.修改Rou ...
随机推荐
- 指定路径下建立Access数据库并插入数据
今天刚刚开通博客,想要把我这几天完成小任务的过程,记录下来.我从事软件开发的时间不到1年,写的不足之处,还请前辈们多多指教. 上周四也就是2016-04-14号上午,部门领导交给我一个小任务,概括来讲 ...
- 深入理解计算机系统chapter5
编写高效的程序需要:1.选择合适的数据结构和算法 2.编译器能够有效优化以转换为高效可执行代码的源代码 3.利用并行性 优化编译器的局限性 程序示例: combine3的汇编代码: load-> ...
- maven详解之结构
maven 父子关系 父项目中打包方式必须是pom 如 <packaging>pom</packaging>,父项目中使用<modules><module& ...
- Paint the Grid Again ZOJ - 3780 拓扑
Paint the Grid Again Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu [ ...
- http://codeforces.com/contest/845
A. Chess Tourney time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- 使用python实现后台系统的JWT认证(转)
今天的文章介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良. 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的.认 ...
- 通过修改 LayoutInflater,全局替换字体!!!
序 在 Android 下使用自定义字体已经是一个比较常见的需求了,最近也做了个比较深入的研究. 那么按照惯例我又要出个一篇有关 Android 修改字体相关的文章,但是写下来发现内容还挺多的,所以我 ...
- VB.NET 中 ComboBox 如何清除选项--- 使用Dataset 赋值 DataSource 的时候
如题: 在 使用Dataset 赋值 DataSource 的时候,网络上很多都是:ComboBox2.DataSource = Null 然并卵,很高兴告诉大家:Null 在VB.NET中是没用的: ...
- Redis缓存项目应用架构设计一
一些项目整理出的项目中引入缓存的架构设计方案,希望能帮助你更好地管理项目缓存,作者水平有限,如有不足还望指点. 一.基础结构介绍 项目中对外提供方法的是CacheProvider和MQProvider ...
- 怎样清理c盘垃圾
休眠文件清理 休眠文件(hiberfil.sys)是,当你的电脑进入休眠状态时,系统临关闭前会将所有内存内容写入hiberfil.sys文件.当你重新打开电脑时,系统在将hiberfil.sys文件内 ...