イベントハンドラに処理を追加する方法

このQ&Aのポイント
  • JavaScriptを使用してbodyタグのonloadイベントハンドラに処理を追加する方法を教えてください。
  • 既存の処理を残しつつ、イベントハンドラにさらに処理を加える方法を教えてください。
  • 採用した方法では、追加した処理が正しく実行されず、エラーが発生してしまいます。どうしたら解決できるでしょうか。
回答を見る
  • ベストアンサー

イベントハンドラに処理を追加するには?

例えば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()の実行 となりました。(これもなぜこうなるのかよくわかりせん) 以上、イベントハンドラに最初から任意に入れられている処理を残しつつ、 さらに処理を加えるにはどうすればよいのかご教示お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • susie-t
  • ベストアンサー率86% (37/43)
回答No.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
OKbokuzyo
質問者

お礼

回答ありがとうございます。 なるほど、「こっちの方がいい!」というのは特に明確ではないのですね。 >>私は単にその場で使いやすいのを使うことにしています 確かに利用する側の立場にしてみればクロスブラウザなど考慮しないでいい方を選びますよね。 私のつたない文章から、丁寧にいくつも回答していただき、非常に助かりました。 本当にありがとうございました。

その他の回答 (2)

  • susie-t
  • ベストアンサー率86% (37/43)
回答No.2

> 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で登録された関数の実行順序は登録順序ではないので注意してください。)

OKbokuzyo
質問者

お礼

すみません、動きました。 開発環境として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として実装すべきと考えておいてよいのでしょうか?

  • susie-t
  • ベストアンサー率86% (37/43)
回答No.1

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)、興味があったら調べてみてください。 参考になれば幸いです。

OKbokuzyo
質問者

お礼

丁寧な回答をありがとうございます。 なるほど。 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」ですね。。。

関連するQ&A

  • 【DOM】HTMLのタグに対してはElementインターフェースが使えない?

    HTMLの「document」はXMLDocumentと完全に見立ててDOMを利用できないのでしょうか? <html>   <style>     .foo{       background: #999999;     }   </style>   <body>     <input class="foo" type="text" value="NNNN"/>   </body>   <script language=JavaScript type=text/javascript>   function hoge(){     var Nodes;     Nodes = document.getElementsByTagName("input");     alert(Nodes.item(0).nodeName)     alert(Nodes.item(0).getAttributeNode("class"))     alert(Nodes.item(0).hasAttributeNode("class"))   }   hoge();   </script> </html> 上記のようなコードを書いてもアラートに「foo」と表示されません。 また、hasAttributeNodeにおいては全く反応がありません。 DOMのElementインターフェースが使えないとすれば、 JavascriptからclassやonClickのイベントハンドラなど、 属性を動的に変更するにはどうすればいいでしょうか? 制限事項としてid属性やname属性は使用できません。 IE6での使用です。 以上、よろしくお願いします。

  • 動的にイベントハンドラ生成する際に引数がある関数を作る

    お世話になっています、ご質問があります。 以下の場合 --hogeA.html-- <html> <head> <script type="text/javascript" src="./**/hogeB.js"></script> </head> <body onload="javascript:hoge.init()"> <input type="text" name="hogehoge" value=""> </dody> </html> --hogeB.js-- hoge = { init : function(){ var BodyElement = document.getElementsByTagName('INPUT'); BodyElement.onBlur = this.setOnBlurAction; }, setOnBlurAction : function(value){ ****(省略)**** } } 上記の場合に、onBlurイベントハンドラ関数を生成し、 画面上でonBlurイベント時にsetOnBlurActionを実行させる予定です。 引数のある関数の場合、動的にイベントハンドラ関数を生成する際はBodyElement.onBlur = this.setOnBlurAction; では駄目な気が致しますが、どうすれば良いでしょうか。 どなたかご教授願います。

  • イベントハンドラに設定された関数を取得し、実行するには?

    <html>   <body>     <script language="JavaScript" type="text/javascript">       function test(){         alert("testです")       }     </script>     <input id="btntest" type="button" value="test" onclick="test()"/>   </body> </html> このhtml文書に対し、 ・test(); ・document.getElementById("btntest").click;(ByTagName等を使用しても同じ方法とする) 上記方法以外にJavaScriptを用いて、 test()を実行するにはどうすればよいでしょうか? var eventobj = document.getElementById("btntest").onclick; eval(eventobj); 上記みたいな形でevalをよくわからずに試してみましたがダメでした。

  • window.onloadでのfunction

    javascript初心者で質問自身が僕が解決したい問題の原因かどうかも解らずに質問しています。 <script type="text/javascript"> <!-- function hoge_1() { ~処理1~ } function hoge_2(hiki_suu) { ~処理2~ } window.onload = function() { document.getElementById("button_1").onclock = hoge_1; document.getElementById("button_2").onclock = hoge_2("watasu"); } // --> </script> 上記のようにページheadにscriptを配置したとします。ページ上のbutton_1がクリックされると処理1が実行されるのですが、hoge_2のように引数を使ってしまうと、onload時に処理2を実行してしまい、button_2は有効に動作しません。 functionの引数の問題なのか、window.onloadの作法なのか、なにが悪いのか全く解らず質問しています。 ご指導のほどよろしくお願いいたします。

  • innerHTMLが動作しない。

    JavaScriptをHTMLファイルに記述した場合、最初にfunctionスコープ内の動作以外は全て行なわれますよね。例えば、 <script type="text/javascript"> <!-- alert("test"); //--> </script> と書いた場合、ページの表示と同時にアラートが出ます。しかし上のalertの部分をdocument.getElementById("test").innerHTML = "test";にすると、これが実行されないのです。もちろん<div id="test"></div>タグはちゃんとbodyタグ内に記述してあります。functionを定義してbody onLoadで呼び出す方法もありますが、できればfunctionをむやみに使いたくないので、先のalertの時のように動作させたいのです。 これが動作しない原因は何なのでしょうか?

  • 下記コードの実行方法について質問です。

    問題のコードは下記ですが、 bodyタグに onLoad="firstFunc()" と書かずに実行したいのですが、 スマートな方法はないでしょうか? よろしくお願いいたします。 <script type="text/javascript"> function firstFunc(){ var aFunc = document.getElementById('btn'); aFunc.onclick = function(){ alert('りんご'); } } </script> </head> <body onLoad="firstFunc()"> <button id="btn" name="ボタン">getElementByIdでonclickのイベントを追加できる。</button> </body>

  • INPUTタグ以外からイベントハンドラを起動する方法

    はじめまして。 いろいろ調べたのですが、的確な答えが見つかりませんでしたので、ご教授お願いいたします。 訳あってonchangeイベントをタグの外から起動したいのですが、関数に括弧を付けると「実装されていません」というエラーが出てしまいます。 括弧を付けていない関数はうまく起動します。 どうしても関数に引数を渡してあげたいのですが、どのようにすればよいのでしょうか? 動作環境は IE5.5 windows2000 ASPにてJavaScriptを作成しています。 以下ソースを簡略化して記述しました。 よろしくお願いいたします。 <html> <head> <script TYPE="text/javascript"> <!-- function f_AAA(){ alert("AAA"); } function f_BBB(a_value){ alert(a_value); } --> </script> </head> <body> <form> <input type="text" name="text1" value="1"> <input type="text" name="text2" value="2"> <script TYPE="text/javascript"> <!-- // ↓括弧の付いていない関数は起動します。 document.forms[0].text1.onchange = f_AAA; // ↓括弧の付いている関数は起動しません。 document.forms[0].text2.onchange = f_BBB("OK"); --> </script> </body> </form> </html>

  • イベントハンドラを使わずに実行するには?

    googleのように、ページが読み込まれたらフォームにフォーカスを 移すということをやりたいのですが、onLoadのようなイベントを 使わずに行うことは出来ますでしょうか? 掲示板でこの機能を使いたいと思っています。しかし、全てのページに フォームがあるわけではないので、<body onLoad="~">で実現すると フォームがない時にエラーが発生してしまいます。 document.write( "hoehoe" ); が直書きで実行されるなら同じようにできるのでは? と思って <script> <!-- document.form.comment.focus(); // --> </script> とやってみましたができませんでした。 onLoadを使わない方法、もしくは<body>以外でonLoadを使う方法が ありましたら是非教えてください。

  • <body onload=""> と window.onload

    JavaScriptのonload処理についての質問です。 現在Java、JSP、JavaScript等でWebアプリケーションを作成しているのですが、 bodyタグ中のonloadに記載したファンクションが時々呼ばれないという問題が起きています。 (こんな感じで記述  <body onload="hoge();hogehoge();">  hogehoge()がたまに呼ばれないことがある・・・) これを回避する方法として、「onload処理をwindow.onloadに記述すれば良い」 という話を聞きました。 (こんな感じで記述  <script>    window.onload = function(){ hoge();hogehoge(); }  </script> ) 「bodyタグ中に記述するとたまに呼ばれないものが、window.onloadに記述すると確実に呼ばれる」 なんてことがあるのでしょうか? 「2つめのファンクションが呼ばれない」という現象がたまにしか発生しないので、 window.onloadに記述する方法で確実に呼ばれるようになったという保証がとれません。 知識として知っている方がいれば是非教えていただきたいです。 よろしくお願い致します。 ※ブラウザはIEを使用  バージョンは IE → 6.0      JavaScript → 1.1 です。  

  • HTMLページ内のタグに対してのイベント

    HTMLページ内のタグに対してのイベント getElementsByTagNameで指定したタグの部分(画像やリンク)をクリックすると関数を呼び出すという動作をやりたいのですが、どうも上手くいきません。 試しに下記のようなプログラムを作ってみたのですが、ページを表示した後すぐにalert関数が呼び出されてしまいます。 あるタグの部分を押したときに関数を呼び出すというやり方を知っている方がおられましたら、ご教授願います。 ひとつひとつにIDを割り当てるというやり方でなくて、タグ別にイベントを判定するやり方を考えています。 <html xmlns="http://www.w3.org/1999/xhtml" > <head>   <title></title>   <script type="text/javascript">    window.onload = function ini(){     document.getElementsByTagName("img").onClick = alert("これは画像です");    }   </script> </head> <body>  <img src="..." />  <img src="..." />  <img src="..." />  <img src="..." /> </body> </html>

専門家に質問してみよう