Javascript関連情報

更新日:2006年02月26日

window.onloadを待たずにDOM処理を開始する

今回は、ページのHEAD内でDOM要素生成してエラーに見舞われた方や、ページ構築完了後、onloadでスクリプトを開始するまでの間ユーザーを待たせるのがつらいという方限定の少し偏った(?)Tipsです。


window.onloadを待たずにDOM処理を開始する

紹介する前に断っておきますが、これは、HTMLやXHTML的にはお行儀の良い方法ではありません。しかし、ユーザー側へパフォーマンスを提供しつつ、管理上もスクリプトをBODYから分離したいといったケースでは効果的です。

次のサンプルは、<body>要素の開始位置を移動する方法を、スクリプトで再現したものです。いろいろな方法がありますが、とりあえず、getElementsByTagNameメソッドを使ってBODYの存在を確認し、なければ追加するという方法を試してみます。

サンプル test5.htm
<html>
<head>
<script type = "text/javascript">
<!--
  if(document.getElementsByTagName('BODY').length==0)
    document.write('<body>');//←ダミーのbodyタグを出力

  var ele = document.createElement('DIV');
  ele.setAttribute('id','testDIV');
  ele.setAttribute('width','200');
  ele.style.color = 'red'
  ele.innerHTML="test";
  document.body.appendChild(ele); //←エラーになりません
//-->
</script>
</head>
<body>←body要素の開始位置
</body>
</html>


一応、このサンプルをW3Cの「マーク付け合法化サービス」Markup Validation Servicev0.7.2 を通過するように修飾してみたら( test5.htm)、「This Page Is Valid XHTML 1.0 Strict!」のお墨付きはいただけましたが、まぁ、ジョークと思ってください。この方法がW3C的に合法でないことは明らかです(ただ、もし、もっと多くの部分をスクリプトで生成するならおそらくこの問題は無くなるでしょう)。

(一応、念のためにですが、チェックをかけると、HTML Validation Resultsでも、「Congratulations, no errors!」で、慶応のAnother HTML-lintはW3Cよりも少し厳しいですがそれでも一応「よくできました」にはなります。)

さて、このサンプルは、DOMを実装した最近の大半のブラウザで、問題なく動作します。ただ、文法的にはやはり、2重のBODYが気になります。では、この場合、どちらのBODY要素が有効なのでしょうか?

ちょっと試してみましょう。

サンプル test6.htm
<html>
<head>
<script type = "text/javascript">
<!--
  alert('1::'+document.getElementsByTagName('BODY').length)

  if(document.getElementsByTagName('BODY').length==0)
    document.write('<body>');//ダミーのbodyタグを出力

  var ele = document.createElement('DIV');
  ele.setAttribute('id','testDIV');
  ele.setAttribute('width','200');
  ele.style.color = 'red'
  ele.innerHTML="test";
  document.body.appendChild(ele); //←エラーになりません

  alert('2::'+document.getElementsByTagName('BODY').length)
  
//-->
</script>
</head>
<body onload="alert('onload::'+document.getElementsByTagName('BODY').length)">
</body>
<script type = "text/javascript">
<!--
  alert('3::'+document.getElementsByTagName('BODY').length)
//-->
</script>
</html>

結果(Win e6,e7b,f1.5,o8,o9b, Mac s1.24,s2,e5, Linux k3)

1::0
2::1
3::1
onload::1

つまり、ダミーのbodyタグをdocument.writeした時点で、BODYオブジェクトが生成され、その後、HTMLで書かれたBODYが出現しても、そのオブジェクトは1個のまま増えません。

ようするに、この場合、最初のBODYだけが有効なのです。

しかし、BODYタグ内のonloadイベントは別管理であって、最初のダミーBODY内に書かれていなければ、HTMLで書かれたBODY内のonloadが有効になります(onloadが両方に書かれていた時は、最初のBODY内のものが有効ですが、先にダミーBODY内に書いてしまうと、HTMLで書いた後ろのBODY内のものが無効になることには注意が必要です。)

最後に、if(document.getElementsByTagName('BODY').length==0)document.write('<body>');よりも簡単な、同様の書き方をいくつか紹介しておきます。

	if(document.body==null)document.write('<body>');
	
	if(!document.body)document.write('<body>');
	
	document.body||document.write('<body>');
	
	document.write((document.body)?'':'<body>');
	
いずれの方法でも、同様に、スクリプト処理の時点でBODYタグが存在しなければ、その場で出力してくれます。

そして、この出力後には、ページ内データの読み込み完了を待つことなく、即座にdocument.body以下へHTMLエレメントの構築を開始できます。

今後、JavaScriptでもUIライブラリなどを使用しつつ、ページ全体をスクリプトで記述するなどというケースも増えてくると思いますが、この書き方は、以上のようないくつかの点を考慮しつつ、BODY要素の位置を明示的に制御する方法のひとつとしても有効かもしれません。



前ページ



1 2
  • 印刷する
  • ブックマークする
  • 携帯に送る
  • ブログに書く

あわせて読みたい

この記事の担当ガイド

写真

高橋 登史朗

Javascriptをはじめ、Ajax、jQueryの著書多数のガイドが、何かと最近騒がれているJa…

続きを読む

住まいには、人の個性がよく現れるもの。同じ空間をどのように使うかで、雰囲気も、快適さも大きく変わってくる。ここでは、「建築家と家を建てる」ガイド の川畑博哉氏が厳選した10軒を紹介し、建築家それぞれのこだわりのポイントを紹介しよう。建築のプロたちが考え出した、マネしたくなるアイデアが満載! さぁ、いますぐチェック!

人気Javascriptランキング

Powered by 価格.com

デジタル関連コミュニティ

北欧好きが、愛用の北欧モノを見せ合うコミュニティ

メルマガ登録

【デジタルメルマガ】オトナのオトコなら知っておきたい、PCやデジモノに関する情報をお届けします。

ショッピングカタログ

All About ウェブマガジン

女性向け

雨が楽しくなる!レイングッズ15

男性向け

マネしたくなるアイデア住宅

All About モバイル

QRコード

All Aboutがケータイで読める!

オススメ記事をメールでチェック

知識・経験を生かして、記事を書いてみませんか?