krzm.jp
黒住浩司 Webサイト

知の好循環

内容

HTML5でHTMLページを記述する際、新しく追加された要素に対応していない、旧バージョンのブラウザーへの対応が必要になります。

新しい要素、すなわち旧いブラウザーにとっては「未知の要素」ですが、少なくともタグとして< >を付けておけば、「何かの要素なんだね、僕にはわからないけど」とブラウザーは好意的に解釈してくれるので、基本的には表示に影響を与えません。ただし、インライン表示で扱われるので、たとえばsection要素のようにブロックレベル表示であるべきものには、スタイルシートで指定しなければなりません。

一方、Internet Explorer 8以下は、「僕にはわからないから迷っちゃうな」という感じで、未知の要素の開始タグと終了タグを、別個の空要素として閉じてしまいます。section要素であれば、以下のような結果になり、囲んであった要素内容は外に放り出されてしまいます。


<section />
要素内容
</section />

というのが、HTML5での注意点なのですが、この記事の本題は、そこにはありません。

こうした未知の要素問題を解決するには、JavaScriptで当該要素を生成し、なおかつスタイルシートも適用しますが、それを一挙に解決してくれるスクリプトを、googleが提供しています。

この「html5.js」スクリプトを、IEコメント分岐を利用して、IE8以下に適用するには、以下のソースコードをHTMLのhead要素内に、なおかつスタイルシートの読み込みや記述をする前に、入れておきます。


<!--[if lte IE 8]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
<![endif]-->

というのも、やはり、この記事の本題ではありません。

本題は、「こうした解決策を、素直に受け入れてよいのか」、というひねくれた話です。たとえば、未知の要素問題の内容が、どのようなものなのかも考えず、ただHTML5ではそれが必要らしいから、と上記のソースコードを言われたとおりに書くだけで、ほんとうに良いのでしょうか?

私が初めてHTML5のことを調べた時、「徹底解説 HTML5 マークアップ ガイドブック」(羽田野太巳・著/秀和システム)という本を読みました。その中で、未知の要素問題も触れられていて、シンプルなサンプルコードが書いてあり、何をすべきなのかが簡単に理解できました。

そのサンプルのうち、配列の書き方だけを自分がふだん使うやり方に変更しただけのものが、以下のコードです。


(function () {
	var ELEMENT = new Array("section","header","article","footer","aside","nav","hgroup","figure","figcaption","time","mark","canvas","video","audio","source","track");
	var MAX = ELEMENT.length;
	for (var i=0; i<MAX; i++) {
		document.createElement(ELEMENT[i]);
	}
}) ();

この中でやっていることは、createElementで要素を作成することですが、その解説も、もちろん本題ではありません。問題の内容と、その解決方法で何をするのか、を理解できたということが重要なのです。

そして、このコードで勉強になったことが、もうひとつあります。ブラウザーにスクリプトを実行させる方法です。


(function () { 処理内容 }) ();

ページの読み込み時に、ブラウザーにスクリプトを実行させる方法として、それまでonloadイベントハンドラを使う方法しか知りませんでしたが、そもそもこの未知の要素解決スクリプトは、onloadで実行できるものではありません。こうした無名関数による実行方法もあるんですね、と参考になり、のちに覚えたイベントリスナーを実行させるときにも役立ちました。

ページやDOMの読み込み時に、addEventListenerでスクリプトを実行させることができ、イベントハンドラよりも便利だったりするのですが、例によってIE8以下は対応していません。それをほったらかしにしておくと、実行時にエラーメッセージが表示されてしまいます。対応の有無をチェックするのは簡単なのですが、ページ読み込み時に実行するものを、対応していない方法でページ読み込み時にチェックするというのは、論理矛盾というか、できない相談です。

しかし、先の無名関数による実行で先にチェックすれば、問題解決です。


(function () {
	if (!document.addEventListener) { //ここで非対応をチェック
		return; //非対応ブラウザーはサヨナラ~
	} else {
		document.addEventListener("DOMContentLoaded", function () {
			処理内容
		}, false);
	}
}) ();

というように、何かを調べると、目的以外の知恵も身につくことがあり、それがまた別の機会に役立つという、アベノミクスなどでは絶対に不可能な、知識の好循環が生まれる(かもしれない)ということです。

googleのスクリプトへのリンクを言われたとおりに書くだけでは、それで終わりです。では、googleのhtml5.jsの中身を調べてみるのは、どうでしょう? このスクリプトでは、スタイル指定まで行っているのですが、はっきり言って私の知識では複雑すぎて、よく分かりません。というより、十数個の要素の作成に、どうしてこんなに処理が必要なのか、その方が不思議です。

という結末になりかねないので、唐突ですが、私はいわゆるJavaScriptライブラリの「jQuery」やそのプラグインも使いません。html5.jsよりもさらに複雑な内容を理解できないのに、それをただ組み込んでいるだけでは、知識が広がらないからです。

故に、当サイトでスクリプトを使用している部分トップページでのナビゲーションボタンの並び替え、スライドショー、記事ページでの見出しリスト、ページ内リンク、脚注の自動生成や画像のポップアップ表示など。この脚注も、実際には本文中に記述してあるのですが、左サイドに抽出し、脚注項目との相互ページ内リンクを自動的に生成しています。は、自分の試してみたい効果や機能を、自分の力でJavaScriptを使って書いたものだけです。そして、そうした制作過程で、また知識が蓄積されたり、応用方法が見つかったりします。

ちなみに、googleのhtml5.jsも、その処理内容はよく分かりませんでしたが、処理結果からは面白いことが判明しました。先にふれたとおり、このスクリプトはスタイル指定までやってくれますが、たとえば新要素のheaderをIE開発者ツールで調べてみると、次のようにスタイル指定されています。

IE開発者ツールの解析画面

それは、ただdisplay:blockが適用されているだけ、なのですが、面白いのは適用対象に挙げられている要素の方です。これらの中に、「main」という名前が見つかります。

HTML5にmain要素なんて無かったはず、ということで色々調べてみると、これはマイナーバージョンアップのHTML5.1で追加されるらしい、ということです。「え、もう5.1なのか」と驚きつつ、HTML5.1の仕様書(作業草案)を確認しても、そこには載っていません。さらに調べてみると、現時点では編集者草案(更新は2013年4月3日、なんと今日!)として提案されていることが判明しました。

そんなところから、またHTML5の現況を理解し直せたという、好循環です。一方で、まだまだ未確定の要素を、すでにスクリプトの中にgoogleは入れているわけですね。やっぱり、そんなものは使いたくありません。

というわけで、仕事で時間に追われ、既存のコードや技法をただ取り込んでいくことが必要な場合もあるかもしれませんが、精神(と時間)に余裕があるときは、色々な方面からの探究を惜しまず、知の好循環を続けていくべきだと、私は考えます。

(もちろん、アベノミクスや自民党がやっていることは、経済の好循環ではなく、格差と貧困の悪循環をもたらすので、私は反対です。)