Внимание!!! Код не проверен!
require.config({
paths: {
jquery: 'lib/jquery/jquery'
}
});
define(['jquery'], function($) {
// Маршрутизатор
// Добавить URL в маршрутизатор
// router.add('/edit/user', function(){alert('User.');});
// Добавить сразу несколько URL в маршрутизатор
// router.add({
// '/edit/user': function(){alert('User.');}
// , '/update/user': function(){alert('Update.');}
// });
// Добавить URL с переменным параметром
// router.add('/edit/user/:id', function(id){alert(id);});
// Добавить URL с переменным содержимым
// router.add('/edit/user/*', function(somethingInURL){alert(somethingInURL);});
// Изменить URL в маршрутизаторе
// router.update('/edit/user', function(){alert('User.');});
// Изменить сразу несколько URL в маршрутизаторе
// router.update({
// '/edit/user': function(){alert('User.');}
// , '/update/user': function(){alert('Update.');}
// });
// Удалить URL из маршрутизатора
// router.remove('/edit/user');
// Удалить сразу несколько URL из маршрутизатора
// router.remove('/edit/user', '/update/user');
// Перейти по конкретному URL
// router.go('/edit/user');
// Начать отслеживание изменения URL в адресной строке
// router.start();
// Остановить отслеживание изменения URL в адресной строке
// router.stop();
var router = {
// Массив для хранения маршрутов URL
routes: []
// Добавление маршрута URL и функции, вызываемой при переходе на него, в массив для хранения маршрутов
, add: function (path, callback) {
var i
, len
, notFoundPath = true;
if (Object.prototype.toString.call(path) === '[object Object]') {
for (var key in path) {
router.add(key, path[key]);
}
} else {
if (Object.prototype.toString.call(path) === '[object String]') {
path = path
.replace(/[-[\]{}()+?.,\\^$|#\s]/g, '\\$&') // ESC
.replace(/:([\w\d]+)/g, '([^\/]*)') // ARG_NAMED
.replace(/\*([\w\d]+)*/g, '(.*?)'); // ARG_SPLAT
path = new RegExp('^' + path + '$');
}
for (i = 0, len = router.routes.length; i < len; i++) {
if (router.routes[i].path === path) {
router.routes[i].path = path;
router.routes[i].callback = callback;
notFoundPath = false;
break;
}
}
if (notFoundPath) {
router.routes.push({
'path': path
, 'callback': callback
});
}
}
}
// Изменение в массиве для хранения маршрутов функции маршрута URL, вызываемой при переходе на него
, update: function (path, callback) {
var i
, len
, notFoundPath = true;
if (Object.prototype.toString.call(path) === '[object Object]') {
for (var key in path) {
router.add(key, path[key]);
}
} else {
if (Object.prototype.toString.call(path) === '[object String]') {
path = path
.replace(/[-[\]{}()+?.,\\^$|#\s]/g, '\\$&') // ESC
.replace(/:([\w\d]+)/g, '([^\/]*)') // ARG_NAMED
.replace(/\*([\w\d]+)*/g, '(.*?)'); // ARG_SPLAT
path = new RegExp('^' + path + '$');
}
for (i = 0, len = router.routes.length; i < len; i++) {
if (router.routes[i].path === path) {
router.routes[i].path = path;
router.routes[i].callback = callback;
notFoundPath = false;
break;
}
}
if (notFoundPath) {
router.routes.push({
'path': path
, 'callback': callback
});
}
}
}
// Удаление маршрута URL и функции, вызываемой при переходе на него, из массива для хранения маршрутов
, remove: function () {
var tempArray = []
, argsLength = arguments.length
, routesLength
, path
, i;
if (argsLength > 0) {
for (;argsLength--;) {
path = arguments[argsLength];
path = path
.replace(/[-[\]{}()+?.,\\^$|#\s]/g, '\\$&') // ESC
.replace(/:([\w\d]+)/g, '([^\/]*)') // ARG_NAMED
.replace(/\*([\w\d]+)*/g, '(.*?)'); // ARG_SPLAT
path = new RegExp('^' + path + '$');
for (i = 0, routesLength = router.routes.length; i < routesLength; i++) {
if (router.routes[i].path !== path) {
tempArray.push(router.routes[i]);
}
}
router.routes = tempArray;
}
}
}
// Настройка кэширования содержимого и определение поддержки браузером history API
, history: {
cache: false
, support: ('history' in window)
}
// Запуск маршрутизатора для начала отслеживания изменений URL в адресной строке
, start: function () {
if (router.history.cache) {
setTimeout(function(){ // Хак для браузеров на основе WebKit
$(window).bind('popstate', router.change);
}, 0);
} else {
$(window).bind('hashchange', router.change);
}
router.change();
}
// Остановить отслеживание изменения URL в адресной строке
, stop: function () {
if (router.history.cache) {
setTimeout(function(){ // Хак для браузеров на основе WebKit
$(window).unbind('popstate', router.change);
}, 0);
} else {
$(window).unbind('hashchange', router.change);
}
}
// Текущий URL в адресной строке
, currentPath: null
// Функция перехода по произвольному URL
, go: function (path) {
if (router.history.cache) {
history.cache.pushState({}, document.title, router.getHost() + path);
} else {
window.location.hash = path;
}
}
// Функция для обработки собтия изменения URL в адресной строке
, change: function() { // Здесь важно ссылаться на router, а не на this, так как метод change вызывается в контексте window, а не в контексте router
var path = router.history.cache ? router.getPath() : router.getFragment()
, routesLength = router.routes.length
, route
, i;
if (path === router.currentPath) {return;}
router.currentPath = path;
for (i = 0; i < routesLength; i++) {
route = router.routes[i];
if (router.match(path, route.path, route.callback)) {return;} // Провести сопоставление текущего URL с маршрутом из массива routes
}
}
// Функция для сопоставления текущего URL с маршрутом из массива routes
, match: function (path, routePath, routeCallback) {
var match = routePath.exec(path) // Выполнить регулярное выражение из маршрута routes для данного пути
, params;
if (!match) {return false;}
params = match.slice(1);
routeCallback.apply(routeCallback, params);
return true;
}
// Методы для получения различных частей адреса URL
, getPath: function() {
return window.location.pathname; // Результат: /edit/user/5
}
, getHash: function() {
return window.location.hash; // Результат: #comment-25
}
, getHost: function() {
return ('' + window.location).replace(router.getPath() + router.getHash(), ''); // Результат: http://site.com
}
, getFragment: function() {
return router.getHash().replace(/^#!*/, ''); // Результат: comment-25
}
};
return router;
});
Комментариев нет:
Отправить комментарий