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();
このような式があるので、ブラウザの実装の差を埋めるためのなんだと推測できますが・・・ここは知識足らずでしっかり説明できない部分が多い。