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 ...
随机推荐
- EntityFramework Core饥饿加载忽略导航属性问题
前言 .NET Core项目利用EntityFramework Core作为数据访问层一直在进行中,一直没有过多的去关注背后生成的SQL语句,然后老大捞出日志文件一看,恩,有问题了,所以本文产生了,也 ...
- 自定义流程gooflow2.0+自定义表单
一.功能简介 gooflow功能清单1.自定义流程绘制2.自定义属性添加3.支持3种步骤类型普通审批步骤自动决策步骤手动决策步骤 4.决策方式(支持js决策,sql语句决策) 5.审批人员参与方式,可 ...
- jmeter测试教程
http://www.cnblogs.com/TankXiao/p/4045439.html
- 初始Socket编程(python)
通信双方要有一个服务端和一个客户端,所以要分开去写代码. 所以我创建了两个py程序,第一个是服务端:iServer.py 和客户端 iClient.py 服务端: #coding:utf-8from ...
- 【NOIP2016提高组day2】蚯蚓
那么我们开三个不上升队列, 第一个记录原来的蚯蚓, 第二个记录乘以p的蚯蚓 第三个记录乘以(1-p)的蚯蚓, 在记录每条就要入队列的时间,就可以求出增加的长度 每次比较三个队列的队首,取最大的值x的切 ...
- PyCharm基本操作
1.1 PyCharm基本使用 视频学习连接地址:http://edu.51cto.com/course/9043.html 1.1.1 在Pycharm下为你的Python项目配置Python解释器 ...
- vim环境设置(应用于python编程)
1. 安装完整的vim # apt-get install vim-gnome 2. 安装ctags,ctags用于支持taglist,必需! # apt-get install ctags 3. 安 ...
- SQL SERVER 查看日志大小及日志已满的处理方法 (转)
--解决方法 --日志文件满而造成SQL数据库无法写入文件时,可用两种方法: --查看数据库日志大小 dbcc sqlperf(logspace) --清空日志. --1.打开查询分析器,输入命令 D ...
- PPT的应用
ppt是Office中一个制作演示文稿的一个办公软件使阐述过程简明而又清晰,轻松又丰富详实,从而有效表达自己以及与他人沟通,所创建的文件被称为电子演示文稿,其扩展名为.PPT.一个演示文稿由若干张电子 ...
- Java 线程基本知识
线程 线程和进程 进程 : 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程 : 线程是进程中的一个执行单元(执行路径 ...