2005年9月19日月曜日

onload時に複数のfunctionを実行するJavaScript

昨日に引き続きJavaScriptねたです。
ページを表示した時点でJavaScriptを実行したい場合、
>

window.onload=function(){ alert('called when window is loaded.'); }
<
のようにwindowオブジェクトのonloadイベントに実行したいfunctionをセットしてやればいいのですが、これだと、オンロード時にひとつのfunctionしか実行できません。
そこで、オンロード時に複数のfunctionを実行できるようなスクリプトを書いてみました。今回のコードはnaoyaさんのprototype.js でデザインパターン - IteratorのエントリにあるIteratorパターンのコードをそのまま借りたリスペクト指向プログラミングになってますw

>

//multiple_onload.js
var OnloadFunction = Class.create();
OnloadFunction.prototype = {
initialize : function(func) {
this.func = func;
},
getFunc : function() {
return this.func;
}
};

var OnloadFunctions = Class.create();
OnloadFunctions.prototype = {
initialize : function() {
this.last = 0;
this.functions = new Array();
},
getFunctionAt : function(index) {
return this.functions[index];
},
appendFunction : function(func) {
this.functions[this.last] = func;
this.last++;
},
getLength : function() {
return this.last;
},
iterator : function() {
return new OnloadFunctionIterator(this);
}
}

var OnloadFunctionIterator = Class.create();
OnloadFunctionIterator.prototype = {
initialize : function(functions) {
this.functions = functions;
this.index = 0;
},
hasNext : function () {
return this.index < this.functions.getLength();
},
next : function() {
return this.functions.getFunctionAt(this.index++);
}
}

var onloadFunctions = new OnloadFunctions();

function multipleOnload () {
var it = onloadFunctions.iterator();
while (it.hasNext()){
var func = it.next();
func.func();
}
}

window.onload = multipleOnload;

<

使用方法はこんな感じです。
動作させるにはprototype.jsが必要なので最初にインクルードしています。

>


<html>
<head>
<script type="text/javascript" src="/js/prototype-1.3.1.js" ></script>
<script type="text/javascript" src="/js/multiple_onload.js" ></script>
<script type="text/javascript">
functon foo() {alert('foo');}
functon bar() {alert('bar');}
functon baz() {alert('baz');}

onloadFunctions.appendFunction(new OnloadFunction(foo) );
onloadFunctions.appendFunction(new OnloadFunction(bar) );
onloadFunctions.appendFunction(new OnloadFunction(baz) );
</script>
</head>
<body>
...
</body>
</html>

<
まず、multiple_onload.jsをインクルードしておきます。そして、定義したfunctionをappendFunctionメソッドを使ってセットしておきます。
これでfoo,bar,bazがオンロード時に順番に実行されます。


7 件のコメント:

  1. functon foo() {alert('foo');}
    functon bar() {alert('bar');}
    functon baz() {alert('baz');}
    window.onload=function(){foo();bar();baz();}
    こんな感じに書くのと比べて、どのような利点があるのでしょうか?

    返信削除
  2. プリン大使2005年9月20日 3:17

    そりゃ勿論、リスペクト指向で実装されてるってとこが利点なのでは?

    返信削除
  3. そうそうリスペクト指向で・・・ってところはおいておいてw、
    常にオンロード時に実行するfunctionと、ある特定のページでしか実行しないfunctionがある場合にこういう風に書いておくと便利だと思います。
    常に実行するfunctionは
    //onload_functions.js
    onloadFunctions.appendFunction(new OnloadFunction(foo) );
    onloadFunctions.appendFunction(new OnloadFunction(bar) );
    onloadFunctions.appendFunction(new OnloadFunction(baz) );
    みたいな外部スクリプトを用意して、ヘッダで読み込むようにしておいて、
    特定のページでしか実行しないfunctionについては、各ページでonloadFunctions.appendFunctionを使って追加できます。

    返信削除
  4. なるほど、納得しました。

    返信削除
  5. addEventListener とかと比べてどの辺が優位なんでしょうか?

    返信削除
  6. 恥ずかしながら、addEventListenerを知りませんでした。
    これを使えば、ひとつのイベントに複数のfunctionを登録できるのですね。勉強になりました。
    ちょっと調べたのですが、DOM Level2ではイベントハンドリングにaddEventListenerを使うことになっているのですね。
    そんで、IEではDOM Level1までしかサポートされてないため、addEventListenerが使えない。変わりにattacheEventという関数があると。
    あと、試した限りだとaddEventListenerとattachEventとで、登録したfunctionの実行順が逆になるみたいですね。
    その辺の差異が吸収されてるって点で優位とかこじつけてみます。

    返信削除
  7. はじめまして。音楽をやっているMasa Okaといいます。
    JavaScriptで、onLoad時にresizeTo()とfocus()を同時に実行させるのがなかなか上手くいかず困っている時に検索でここを見つけ、とても助かりました。
    ありがとうございます!!
    www.masaoka.infoの日記ページに、プチ「ありがとう」リンクを貼りました。もしマズかったら言って下さい。
    これからもイイ記事楽しみにしてます。では!

    返信削除