blog.kur.jp

バイオリンと山、自転車をこよなく愛するkurのチラシの裏。たまには技術的なことを書いたりするかも知れません。

JavaScriptにおけるエレメントの指定ではまった

JavaScriptを使ったWebブラウザ上で動くアプリを書こうと思った時にまずぶち当たるのが,ブラウザによる挙動の違いです.で,そういったことを解決する方法として,prototype.jsやらjQueryやらDojoやらのライブラリを使うって言う方法があります.

ところが,すごく単純な部分ではまってしまったので,忘れないようにメモ.

先日,ブラウザの画面内のどこかをクリックしたら(つまり,どこをクリックしてもってこと)アラートを出すスクリプトを書きたいと思って,こんな感じで書きました.

<script type="text/javascript" src="./prototype-1.6.0.2.js"></script> <script type="text/javascript"> function handler(e) { alert('クリックされました'); } Event.observe(window, 'click', handler); </script>

ところが,Firefoxではこれで動くんですが,IEでは動いてくれません.Javascriptistによると,Event.observeの第一引数は監視したいエレメント, 第二引数はイベント名, 第三引数はイベント時関数だそうですので,とりあえず試行錯誤してみることに.

最初に思いついたのはイベント名をいじってみるってこと.click以外なら動いたりするんじゃないか?というわけで,clickではなく,loadにしてみました.loadにすると,ページを読み込んだときに,アラーとを出してくれるはずです.

<script type="text/javascript" src="./prototype-1.6.0.2.js"></script> <script type="text/javascript"> function handler(e) { alert('読み込まれました'); } Event.observe(window, 'load', handler); </script>

実際に,ブラウザで実効してみると,IEでもFirefoxでも問題なく動作します.clickとloadで何が違うんでしょうか.イベントの種類が違うってのは確かにあるんですが,loadはhtmlそのものと言うか,ブラウザの読み込み動作に関係するイベントで,clickはhtmlの内容と言うか,ブラウザの読み込み内容に関するイベントだからなのかな?と考えてみました.

もし,そうだとすれば,ですよ.windowはブラウザのwindowを表すオブジェクトですから,表示内容に関するオブジェクトを指定してやれば,IEでもClick時に動作を実行することができるのでは?じゃぁ,Event.observeの第一引数を弄ってみるか….

というわけで,エレメント名をいじってみることに.JavaScriptは不慣れですが,どうせオブジェクトの概念は階層構造になってて他の言語と大差ないだろう.っていう安易な考えのもと,オブジェクトの階層構造に関する資料を検索.その結果,wikipediaでそれっぽい資料を発見しました.で,ためしにこんな感じでdocumentって指定してみることに.

<script type="text/javascript" src="./prototype-1.6.0.2.js"></script> <script type="text/javascript"> function handler(e) { alert('クリックされました'); } Event.observe(document, 'click', handler); </script>

うん.ビンゴでした.動いた動いた.こうすれば,Firefoxでも,IEでも動く.解決解決.

まとめ

グーグル先生に聞いてみると,

Event.observe(document に一致する日本語のページ 約 3,950 件中 1 - 10 件目 (0.10 秒) Event.observe(window に一致する日本語のページ 約 6,520 件中 1 - 10 件目 (0.10 秒)

って言う結果が得られることからもわかるように,ネット上のサンプルを見てるとEvent.observeの第一引数にwindowを指定したものが多いんだけど,Event.observeの第一引数にはdocumentを指定したほうが良いみたい.ていうか,そうしないとIEでちゃんと動かない.

理由は,イベントの種類の違いと,Windowオブジェクトとdocumentオブジェクトの関係にあるのかなー,とか思ってみたものの,検証するまでには至ってません.もうちょっと,JavaScriptを勉強しないとなー.