2007年7月19日木曜日

既定の関数にユーザー定義関数を追加する

ニコニコ動画は動画プレイヤーの拡大表示から元の表示に戻す時に、restorePlayer() というJavaScriptの関数を使用しています。

function restorePlayer() {
 Event.stopObserving(window, "resize", fitPlayerToWindow, false);
 $("flvplayer").setStyle({ width: "", height: "" });
 $$("html", "body").invoke("setStyle", { margin: "", padding: "", width: "", height: "" });
 $("flvplayer_container").setStyle(containerStyle);
 $("PAGEHEADER", "WATCHHEADER", "WATCHFOOTER", "PAGEFOOTER").invoke("show");
 Element.scrollTo($("flvplayer_container"));
}

.invoke("show") で拡大表示時に隠れていた "PAGEHEADER", "WATCHHEADER", "WATCHFOOTER", "PAGEFOOTER" のIDを持つ要素を再び表示させています。 困ったことにこれは、Proxomitron(ユーザーJavaScript)で非表示にした要素も表示させてしまいます。 そこで、restorePlayer() に再び該当要素を非表示にする動作を入れるために、作成したのが以下の関数。

// ----------- 関数の定義

/* restorePlayer() にユーザー定義関数を追加 */
function AddrestorePlayer(func){
   var oldrestorePlayer = restorePlayer;

   restorePlayer = function(){
    oldrestorePlayer();
    func();
   }
}

/* 動画下のコンテンツ(対応ブラウザ、動画再生プレイヤー つかいかた、Amazonアソシエイト) を隠す */
function HideWatchFooter(){
   var WatchFooter = document.getElementById('WATCHFOOTER');
   WatchFooter.style.display = 'none';
}

// ----------- 実行処理

window.onload = function(){ // ページ読み込みが終了したとき
   HideWatchFooter();
   AddrestorePlayer(HideWatchFooter); // restorePlayer() に HideWatchFooter() を追加
}

このコードは、既存の関数を変更せずに、追加している仕組みが優れています。 restorePlayer() が書き換わっても追従できるのです。

ちなみに、このアルゴリズムは私が考え出したものではなく、Simon Willison’s WeblogaddLoadEventが元となっています。 更にいえば、私が特別英語力に優れているわけでもなく、『DOM Scripting 標準ガイドブック ~やさしく学ぶ、JavaScriptとDOMによるWebデザイン』を参考にしています。

今回のように既存の関数を改変することを、専門用語で関数のオーバーロードと呼ぶようです。 よくある例は、「既存の関数と同じ関数を定義することによって、前の関数を帳消しにして、新しい関数に上書きする」手法です。

/* 既存の関数 */
function restorePlayer() {
   ...(中略)...
}

/* 新しい関数 (同名の関数を定義することで古い関数を上書きする) */
function restorePlayer() {
   ...(中略)...
}

このように、同名の関数を再定義することで前の関数を上書きします。 この記述の後で、restorePlayer() が呼び出された場合、後者の関数を実行することになります。

ラベル: ,

0 件のコメント:

コメントを投稿

登録 コメントの投稿 [Atom]

<< ホーム