behaviour.js リバースエンジニアリング その1 は急いで書いたので、大事な部分を見落としてたように思うので、もうちょっと詳細に見てみます。
おもしろかったのはBehaviour.apply()の部分
apply : function(){
for (h=0;sheet=Behaviour.list[h];h++){
for (selector in sheet){
list = document.getElementsBySelector(selector);
if (!list){
continue;
}
for (i=0;element=list[i];i++){
sheet[selector](element);
}
}
}
},
ユーザーが指定した「セレクタ名:関数」をプールしている配列Behaviour.listから、要素を抜きだして for 文で処理しているんですが。
for (h=0;sheet=Behaviour.list[h];h++){
for (selector in sheet){
list = document.getElementsBySelector(selector);
for〜in〜ステートメントで、sheetオブジェクト { セレクタ名:function(element){ ... } } から セレクタ名を抜き出してgetElementsBySelector()に渡しているのがなかなかスマート。getElementsBySelector()はセレクタ名を引数にとり、HTMLエレメントの配列を返す関数でした。なのでlistにはHTMLエレメントの配列が入る。
(このlist配列とBehaviour.list配列 は 別物なんですよね?名前が同じで、listは先に使われている名前だし、さらにvar宣言も無しに出てくるので違和感を覚える・・・)
そしてapply関数の後半では
for (i=0;element=list[i];i++){
sheet[selector](element);
}
list配列からHTMLエレメントを抜き出してほげほげするんですが
sheet[selector](element);
がお見事な感じ。sheet[selector]で、{セレクタ名:関数} の関数名の部分をひっぱってきて 、()をつけて無名関数の部分を呼び出し実行しています。見慣れない構文だけど、これは関数の呼び出し式なんだな。悩んだ。
addLoadEvent()も面白いことをやってました。
addLoadEvent : function(func){
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
}
addLoadEvenet()は関数を引数にとっています。ほほぅ。Javascriptだと関数も変数と同じように扱えるんだった。
で、
var oldonload = window.onload;
が不思議な式です。イベントハンドラを右辺で使うのは初めて見た。
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
このような式があるので、ブラウザの実装の差を埋めるためのなんだと推測できますが・・・ここは知識足らずでしっかり説明できない部分が多い。