プロが教えるわが家の防犯対策術!

例えばbodyタグのonloadイベントハンドラに
JavaScriptを使って処理を追加するにはどうすればよいのでしょうか?

例)
・rei.htm
<html>
 <script language="JavaScript" type="text/javascript">
 function hoge(){
  alert("hogeです");
 }
 function foo(){
  alert("fooです");
 }
 </script>
 <body onload="hoge();">
 </body>
 <script language="JavaScript" type="text/javascript">
 document.body.onload += foo();
 </script>
<html>
※前提条件として、変更可能な箇所はscriptタグ内のみとなります。


「こんなんでいけないかな?」と思って上記のようにやってみたのですがうまくいきませんでした。
(結果はfoo()のみ実行され、hoge()は実行されませんでした。
alertでbody.onloadの中身を確認すると『function anonymous{hoge();}undefined』と表示されるので、なぜfoo()が実行されてhoge()が実行されないのかよくわかりませんが‥)

また試しに
document.body.onload += foo();
これを以下のように変更してみました。
document.body.onload = foo();

この時は、

・foo()の実行
 ↓
・javascriptエラー
 ↓
・hoge()の実行

となりました。(これもなぜこうなるのかよくわかりせん)

以上、イベントハンドラに最初から任意に入れられている処理を残しつつ、
さらに処理を加えるにはどうすればよいのかご教示お願いします。

A 回答 (3件)

> onloadイベントは、通常JavaScriptからwindow.onloadとして実装すべきと考えておいてよいのでしょうか?



この点に関しては、実は私もはっきりとした根拠があるわけではないんです^^; そういう動作だから、というだけで。(ちょっと検索してみましたが、はっきり説明してくれているところは見当たりませんね・・・)

一見、<body onlaod=~ はwindow.onloadとは別物のように思えるのですが、結局window.onloadに登録されるのは一緒です。IEにおけるdocument.body.onloadも同様です。本来の意味からすると、<body onload=~やdocument.body.onloadはbody部の読み込み完了時に実行されるべきな気もするのですが、実行タイミングははwindowと同じでページ読み込み完了時です。
----------------------------------
<html>
<head>
<script>
</script>
</head>
<body onload="alert('body');">
<script>
//↓コメント外すと「body」が「window」になる。それ以外は変化なし。
//window.onload=function(){alert("window");};
//document.body.onload=function(){alert("window");};
alert((document.body.onload == window.onload)); //IEでtrue
</script>
</body>
<script type="text/javascript">
alert("body end"); //<body onload=~ 等よりも前に実行
</script>
</html>
-----------------------------------
参考URL等、いろいろ議論されている話題なのですが、私は単にその場で使いやすいのを使うことにしています。(無論、無計画だと破綻しますが)

個人的な推測ですが、当初、<body onload=~でページ読み込み時の処理を指定できるようにしていて、その後、DOMにするときに他のイベント(onunload等)と合わせるためにwindowオブジェクトへ移管されたのでは・・・と考えています。(IEは親切心(おせっかい?)からdocument.bodyも有効にしているのだと思います)

答えになってないかもしれませんが、参考になれば幸いです。

参考URL:http://www5d.biglobe.ne.jp/~y0ka/2006-12-07-1.html
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

なるほど、「こっちの方がいい!」というのは特に明確ではないのですね。

>>私は単にその場で使いやすいのを使うことにしています

確かに利用する側の立場にしてみればクロスブラウザなど考慮しないでいい方を選びますよね。


私のつたない文章から、丁寧にいくつも回答していただき、非常に助かりました。
本当にありがとうございました。

お礼日時:2007/09/21 22:40

> windowオブジェクトはattachEvent, addEventListenerを実装していない模様。


あれ、あると思うのですが・・・。むしろdocument.bodyのほうにないような。alert(window.attachEvent);とするとtoStringした結果が表示されませんか?
いちおう、下で動作を確認しました。(WinXP+IE6、Firefox2)
---------------------------------------------------------
<html>
<script>
//イベント登録関数
function observeEvent(element, name, observer){
if (element.addEventListener) {
element.addEventListener(name, observer, false);
} else if (element.attachEvent) {
element.attachEvent('on' + name, observer);
}
}
observeEvent(window, "load", function(){alert("!");});
</script>
<body>
</body>
<html>
---------------------------------------------------------
これでもダメですか?
(余談ですが、attachEventで登録された関数の実行順序は登録順序ではないので注意してください。)
    • good
    • 0
この回答へのお礼

すみません、動きました。

開発環境としてEclipseにAptanaをプラグインして使っているのですが、
「window.」とタイピングしても予測変換一覧にaddEventListenerやattachEventが表示されなかったので
windowにこれらリスナーが実装されていないと早とちりしてしまいました。
(逆に「document.body.」とタイピングすると予測変換一覧にaddEventListenerやattachEventがヒットしたので‥)
今後はあまりIDEを信頼しすぎないように注意します。

これで当初目的は完璧に果たせそうです。
本当にありがとうございます。

教えてもらってばかりで大変恐縮ではあるのですが、
最後にひとつだけ聞かせてください。

私はonloadイベントはbodyタグのonload属性に実装するのが一般的と思っていたのですが、
Firefoxではdocument.body.onloadに対応していないなど、
今回の話によるとbodyタグのonload属性を使用するよりも
JavaScriptのwindow.onloadから実装するほうが一般的なイメージを受けました。
onloadイベントは、通常JavaScriptからwindow.onloadとして実装すべきと考えておいてよいのでしょうか?

お礼日時:2007/09/20 22:25

document.body.onload += foo();



var tmp = window.onload;
window.onload = function(){
tmp();
foo();
}
のようにするのが簡単。

この場合はdocument.bodyよりもwindowのほうが適しています。(document.bodyだとIEはOKだが、FirefoxではNGです)

関数の後ろに()をつけると、読み込み時点で実行されます。提示例の前者の場合、fooはonloadイベントで実行されているのではなく、読み込み時点です。前者の例ではonloadに登録されるのは、「元の関数を文字列化したもの+fooの戻り値(undefined)を文字列化したもの」になります。(数値以外で+=を使うと対象はすべて文字列化されます)

他、addEventListener(Firefox等)、attachEvent(IE)を使用するという方法もありますが、こちらはちょっと癖があるので(特にIE)、興味があったら調べてみてください。

参考になれば幸いです。
    • good
    • 0
この回答へのお礼

丁寧な回答をありがとうございます。

なるほど。
window.onloadというのがあるのですか。
しかし、今回は不特定多数のhtml文書を対象に実装を考えていますので、
window.onloadにどんな処理が記述されていても関係なく処理を追加したいと考えております。
なので、

>>他、addEventListener(Firefox等)、attachEvent(IE)を使用するという方法もありますが

こちらを試してみました。しかし、

・windowオブジェクトはattachEvent, addEventListenerを実装していない模様。
・document.body.attachEvent("onload",foo)としてみたが、実行されなかった。
(※ document.bodyはFirefoxに対応していないということでaddEventListenerは試していません)

ボタンのオブジェクトに対して、attachEvent("onclick",foo)は効いたので
使い方は間違っていないとは思うのですが、なぜでしょうか?

>>関数の後ろに()をつけると、読み込み時点で実行されます。提示例の前者の場合、fooはonloadイベントで実行されているのではなく、読み込み時点です。前者の例ではonloadに登録されるのは、「元の関数を文字列化したもの+fooの戻り値(undefined)を文字列化したもの」になります。

言われてみればそうですよね。
イベントハンドラに関数名で渡す場合は「foo()」ではなく「foo」ですね。。。

お礼日時:2007/09/20 01:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!