DOMの構築待ちイベント

前回は、マジックのように短く高度な処理を記述できるjQueryのメソッドチェーンなどの特徴と、 ダウンロード/設置についてみてみました。

今回は、JavaScriptを実際に使う上でかかせないイベントの扱いについて確認します。

JavaScriptでDOM要素へアクセスする場合には、そのDOM要素のページ読み込みが終了し構築済みでなければなりません。 そのために、<body onload="スクリプト">やwindow.onload=関数などの、ページ読み込み終了を待って動作するイベントが用意されています。

しかし、前者はHTML内にスクリプトを書かなければならず、後者も、ひとつのページで一度しか登録できないため、最近のような複数のコードを 組み立てていくような開発には向きません。

また、複数登録が可能なW3CのDOM仕様に基づくaddEventlistenerは、IEがサポートしておらず、IEの独自実装であるattachEventは、他のブラウザが サポートしないという具合で、イベントに関しては、最近になっても未だにブラウザ間の互換性の無さがコードを複雑にしています。

そこで、最近のJavaScriptライブラリでは、その非互換部分を取り除くこと必須の機能になっており、 jQueryでもクロスブラウザ化されたイベントが用意されています。

まず、DOM要素の構築を待つイベントですが次のような記述になります。
 $(関数);
これだけです。具体的には、たとえば、匿名関数を利用して次のように記述します。
 $(function(){
   $("#myDiv").css("color",red);
 });
あるいは、関数に名前を付けて次のような書き方もOKです。
  $(ini1);
  function ini1(){ $("#myDiv").css("color","red") }

  $(function(){ ini1() });
  function ini1(){ $("#myDiv").css("color","red") }
これは、DOMが準備完了したら、id名が"myDiv"の要素の文字色を赤にする、という意味です。

そして、window.onloadのように画像などすべてのページ要素のロード完了を 待つのではなく、DOMの構築完了で実行されますので、多少待ち時間が少なくなります。

ちなみに、この書き方はjQueryのv1.2からの方法で、もともと、$(document).ready(関数)と書いていたものを簡略化したものです。

そして、 $(関数)は、複数の登録を行っても上書きされることはありません。たとえば、次のようにイベントを登録しても、 jQueryのこのイベントは、 既に書かれている window.onload などと衝突しません。下記の場合は、どのブラウザでも「0,1,3,4」の順で表示されます。
window.onload=function(){alert(2)}
window.onload=function(){alert(3)}
if (window.addEventListener) {
  window.addEventListener('load', function(){alert(4)} , false);
} else if (window.attachEvent) {//IE用
  window.attachEvent('onload' , function(){alert(4)} );
} $(function() {alert(0)}) $(function() {alert(1)})
$(function() {alert(0)})と$(function() {alert(1)}) が最後に書かれているのに最初に実行されていることに注目してください。 DOM未構築のエラーを避けつつ、待ち時間が少ないというわけです。

そして、「2」が表示されないのは、window.onload自身が前のwindow.onloadを上書きしてしまうからです。 したがって、すでにある別のスクリプトと組み合わせるときにもjQueryのこのイベントは安心して使えるわけです。

ただ、DOM構築後、もっと高速に動作させたい時は、(jQueryの話ではなく普通のJavaScript Tipsですが) 構築待ちイベントを使わずに、DOM要素よりも後ろにスクリプトを書く手があります。たとえば、次のような書き方です。 ( ただし、 大概はうまくいきますが、 何らかの理由で構築に時間のかかるDOM(たとえばdocument.writeで書き出すDOMなど)の場合は、タイミングがずれてうまくいかないことがありますので注意は必要です。)
<div id="test">処理したいDOM要素</div>
<script>
  $("#test").css("color","red");
</script>
また、 すでにお気づきとは思いますが、jQueryのイベントのこの$(関数)という書き方は、 前回 $("DIV.testClass").css("color","red") 等と書いていた$()関数の引数が文字列から関数に変わっただけのものです。

このように、jQueryでは、同じ$()関数の引数のタイプを変えるだけで機能が変わる仕組みになっているのです。 また、この関数名「$」は、jQueryオブジェクトへのショートカットなのでjQuery(関数)などと書いても同じ動作をします。


次はjQueryでクリックイベントなどをDOM要素へ割り当てる方法です。