骑驴找蚂蚁

全干工程师

JavaScript实现一个轻量级的路由控制

使用javascript实现一个Slim(php)版路由库...嘻嘻...laughinglaughinglaughinglaughing

(function(root, factory) {
    factory(root);
}(window, function(root) {
    var root = root || window;
    var Route = function(n, cb, gp, id) {
        var name = n,
            callback = cb,
            groups = gp,
            identifier = 'route' + id;
        this.getName = function() {
            return name;
        }
        this.getCallback = function() {
            return callback;
        }
        this.getIdentifier = function() {
            return identifier;
        }
    };
    var Router = function() {
        this.routes = {};
        this.routeCounter = 0;
        this.groups = [];
    };
    Router.prototype = {
        route: function(pattern, callback) {
            if (this.groups.length > 0) {
                pattern = this.processGroup() . pattern;
            }
            var route = new Route(pattern, callback, this.groups, this.routeCounter);
            this.routes[route.getIdentifier()] = route;
            this.routeCounter++;
        },
        processGroup: function() {
            var pattern = '';
            for (var i in this.groups) {
                pattern += this.groups[i].groupPattern;
            }
            return pattern;
        },
        group: function(pattern, callback) {
            this.groups.push({groupPattern: pattern});
            if (callback) {
                callback.call(this)
            }
            this.groups.shift();
        }
    };
    var Slim = function() {
        var router = new Router();
        this.group = function(pattern, callback) {
            router.group(pattern, callback);
        };
        this.map   = function(pattern, callback) {
            router.route(pattern, callback);
        }
        this.routes= function() {
            return router.routes;
        }
        this.parser= function(pattern, pathInfo) {
            var variable,
                regex = /\/\{\w+\}/g,
                regexVar = /\/\{(\w+)\}/g,
                variables = [],
                param = {},
                pathRegex = pattern.replace(regex, "\\/(\\w+)").substr(1),
                matchValue = pathInfo.match(new RegExp(pathRegex));
            while ((variable = regexVar.exec(pattern)) !== null) {
                variables.push(variable[1]);
            }
            if (matchValue < 1) {
                return null;
            }
            if (matchValue.length > variables.length) {
                for (var key in variables) {
                    param[variables[key]] = matchValue[parseInt(key) + 1];
                }
            }
            return param;
        }
    };
    Slim.prototype = {
        dispatch: function() {
            var pathInfo = root.location.pathname,
                routes = this.routes(),
                callback = null,
                param  = {},
                fun,
                name;
            for (var key in routes) {
                name = routes[key].getName();
                if (name === pathInfo) {
                    callback = routes[key].getCallback();
                } else if ((param = this.parser(name, pathInfo)) !== null) {
                    callback = routes[key].getCallback();
                }
                if (callback) {
                    break;
                }
            }
            if (typeof callback === "function") {
                callback.call(this, param);
            } else if (typeof callback === "string") {
                fun = root[callback];
                if (typeof fun === "function") {
                    fun.call(this, param);
                }
            }
        },
        getQuery: function() {
            var query = root.location.search.substr(1);
            if (query === "") {
                return {};
            }
            var queryGroup = query.split('&');
            var groups = {};
            for (var i in queryGroup) {
                var group = queryGroup[i].split('=');
                groups[group[0]] = group[1];
            }
            return groups;
        }
    };
    root['Slim'] = new Slim();
}));
//绑定路由
Slim.map('/lobby/{id}', function(args) {
    console.log(args.id);
});

Slim.map('/hello/{name}', function(args) {
    console.log(args.name);
});
//添加组路由
Slim.group('/group', function() {
    this.map('/group1', function(args) {
        console.log('Hello');
    });
    this.map('/group2', function(args) {
        console.log('World');
    });
});
Slim.dispatch();

留言