backboneルーティングのような純粋なroute(フロントエンドルーティングクライアントルーティングbackboneルーティング)
9100 ワード
backbone、angularは、内蔵のルーティングに慣れているかもしれませんが、この2つのフレームワークのルーティングは非常に優れており、強くて簡単です.
クライアント(ブラウザ)のルーティング原理は簡単で、hashの変化を傍受することです.
以前のアーキテクチャの検討ではdirectorについて述べた.jsというルーティングクラスライブラリは使いにくいので,本稿では,簡潔で非常に使いやすいルーティングクラスライブラリを独自に実現しようと試みる.
原理はまず紹介され、いくつかのステップにほかならない.コンフィギュレーションテーブル(文字列パスと関数のマッピング) を確立するリスニングルーティング ルーティングの変更を処理し、構成テーブルのパスと一致する パスを正規表現 に変換正規exec、マッチング+抽出パラメータ
難点は経路が正規表現に変換されたことであり、directorがうまくいかなかったのはこのステップであり、backboneは非常に強力であるので、backboneというコードをほじくり出してみることができます.
ルーティングテーブル:
経路変更のリスニング:
ルーティングの変更を処理し、正規表現をまとめます.
元の:module 2/:nameから標準的な正則表現になり、その奥義をみんなが悟る
循環一致:
そして...簡単なテストを行います.
この文書のコード:https://github.com/kenkozheng/HTML5_research/tree/master/backbone-route
クライアント(ブラウザ)のルーティング原理は簡単で、hashの変化を傍受することです.
以前のアーキテクチャの検討ではdirectorについて述べた.jsというルーティングクラスライブラリは使いにくいので,本稿では,簡潔で非常に使いやすいルーティングクラスライブラリを独自に実現しようと試みる.
原理はまず紹介され、いくつかのステップにほかならない.
難点は経路が正規表現に変換されたことであり、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]*))?$');
}
元の:module 2/: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