JavaScript プログラミング講座

 

JavaScript と互換モードの関係について

 


■レンダリングモードについて


ブラウザには、レンダリングモードがあります。
 
主に「標準モード」と「互換モード」の2種類があります。
 
レンダリングモードについては、こちらで解説しています。
 

■ Internet Explorer の互換モードについて


Internet Explorer の互換モードには、「IE5 Quirks モード」と「Quirks モード(最新)」の2つがあります。
 
■ IE5 Quirks モードについて
 
「IE5 Quirks モード」とは、Internet Explorer 9 以前の互換モードに相当します。
 
「IE5 Quirks モード」で動作している場合、Internet Explorer 8 から対応しているはずの、ほとんどの API が利用できせん。
 
例えばイベントリスナーは、 Internet Explorer 9 から利用できる機能です。
 
しかし、「IE5 Quirks モード」で動作しているのであれば、イベントリスナーは利用できません。
 
■ Quirks モード(最新)について
 
「Quirks モード(最新)」とは、Internet Explorer 10 以降の互換モードに相当します。
 
互換モードで動作していたとしても、対応している API は、すべて利用できます
 
この仕様は、他のブラウザでは一般的な動作です。
 

■サポートするすべての API を利用するためには?(Internet Explorer 9 以前の場合)

 
互換モード(IE5 Quirks モード)で動作しないように対策する必要があります。
 
ブウラウザがどのようなレンダリングモードで動作するかは、ドキュメントタイプ宣言で決まります。
 
HTML 文書に、「標準モード」で動作する、ドキュメントタイプ宣言を記述するといいでしょう。
 
ドキュメントタイプ宣言を省略した場合、「互換モード」で動作します。
 
■標準モードで動作する、ドキュメントタイプの宣言の例
 
標準モードで動作する例(HTML4.01 Strict)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <body>
  </body>
</html>
 
標準モードで動作する例(HTML5)

<!DOCTYPE html>
<html>
  <body>
  </body>
</html>
 

■「互換表示」機能について

 
Internet Explorer 8 以降から、「互換表示」という機能が利用できます。
 
ユーザーがこの機能を有効にすると、ユーザー側から強制的に「互換モード」で動作させることができます。
 
「互換表示」機能を無効化するには、ドキュメント互換モードを設定する必要があります。
 
 

■ドキュメント互換モードを設定する(「互換表示」機能を無効化する)

 
ドキュメント互換モードを設定すると、「互換表示」機能を無効化する事ができます。
 
ドキュメント互換モードを設定するには、以下の <META> タグを使用します。
 
InternetExplorer 専用のタグです。
 
■ edge モードを設定する
 
edge モードを指定すると、常に最新の標準モードで動作させる事ができます。
 
<HEAD> タグ内の一番上に記述する必要があります。
 
常に最新の「ドキュメント互換モード」で動作させる(「互換表示」機能を無効化する)

<!DOCTYPE html>
<html>

  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  </head>

  <body>
  </body>
</html>
 
■タグの仕様について
 
詳しい仕様は、MSDN が参考になります。
 
http://msdn.microsoft.com/ja-jp/library/cc288325.aspx (ドキュメント互換性の定義)
 

■「開発者ツール」機能について

 
Internet Explorer 8 以降から、「開発者ツール」という機能が利用できます。
 
開発者ツールのメニューから、「ドキュメント互換モード」を一時的に切り替えることができます。
 
この設定は何よりも優先的に反映されます。開発者ツール表示中はご注意下さい。
 
 


 

ドキュメントモードについて

 
 


■ドキュメントモードについて


Internet Explorer の、ドキュメントモードのバージョンを取得するには、documentMode プロパティを使用します。
 
Internet Explorer 7 以前では、対応していません。
 
これは、Internet Explorer 本体のバージョン情報ではありません。
 
Internet Explorer では、互換性のために、古いレンダリングエンジンが複数搭載されています。
 
例えば、Internet Explorer 10 では、「IE10(標準)」「IE9(標準)」「IE8(標準)」「IE7(標準)」「Quirks(互換)」「IE5 Quirks(互換)」が存在します。
 
例えば、Internet Explorer 8 では、「IE8(標準)」「IE7(標準)」「IE5 Quirks(互換)」が存在します。
 
詳しい仕様は、MSDN が参考になります。
 
http://msdn.microsoft.com/ja-jp/library/cc288325.aspx (ドキュメント互換モードの判別)
 

■ドキュメントモードのバージョンを取得する


動作中のドキュメントモードのバージョンを取得する関数です。
 
ドキュメントモードが確定していない段階でアクセスすると、0 値が得られます。
 
6 という値が得られる事はありません。かわりに 7 値が得られます。
 
詳しい仕様は、MSDN が参考になります。
 
http://msdn.microsoft.com/ja-jp/library/cc288325.aspx (ドキュメント互換モードの判別)
 
http://msdn.microsoft.com/ja-jp/library/cc196988.aspx (documentMode)
 
ドキュメントモードのバージョンを取得する関数

// ------------------------------------------------------------
// ドキュメントモードのバージョンを取得する関数
// ------------------------------------------------------------
function DocumentGetDocumentMode (document_obj){

	// Internet Explorer 8 以降
	if(document_obj.documentMode !== undefined){
		return document_obj.documentMode;
	}

	// Internet Explorer 6 ~ 7
	if(document_obj.compatMode !== undefined){
		if(document_obj.compatMode == "CSS1Compat"){
			return 7;
		}
		return 5;
	}

	// 判別不能
	return null;
}
 

■ドキュメントモードのバージョンを設定する

 
ドキュメントモードのバージョンを設定するには、<meta http-equiv="X-UA-Compatible" content="" /> タグを使用します。
 
しかし、余程の致命的な問題でも無い限りは、特定のバージョンの標準モードを指定すべきではありません
 
将来的に該当するドキュメントモードのサポートが終了した場合、閲覧できなくなるかもしれません。
 
「edge モード」の指定は推奨します
 
edge モードを指定すると、常に最新の標準モードで動作します。
 
詳しい仕様は、MSDN が参考になります。
 
http://msdn.microsoft.com/ja-jp/library/cc288325.aspx (ドキュメント互換モードの指定)
 


 

イベントの互換性について

 


■イベントの互換性について

 
■イベントリスナーについて
 
イベントリスナーは、Internet Explorer 9 以降で利用可能です。
 
登録するコールバック関数は、必ず「標準的な仕様」で動作します
 
DOM Event Model については、こちらで解説しています。
 
Internet Explorer 9 は、互換モードに問題があります。
 
IE9 にて、互換モードで動作している場合、イベントリスナーは使用できません。
 
互換モードを無効化するには、edge モードを指定するといいでしょう。
 
コンテキストメニューの表示をキャンセルする

// ------------------------------------------------------------
// コンテキストメニューが表示される直前に実行されるイベント
// ------------------------------------------------------------
document.addEventListener("contextmenu",function (e) {

	// ------------------------------------------------------------
	// リスナーの登録場所(イベント伝達中における現在の場所)
	// ------------------------------------------------------------
	var current_target = e.currentTarget;

	// ------------------------------------------------------------
	// イベントの発生場所
	// ------------------------------------------------------------
	var target = e.target;

	// ------------------------------------------------------------
	// 出力テスト
	// ------------------------------------------------------------
	console.log(current_target);
	console.log(target);
	console.log(e);

	// ------------------------------------------------------------
	// デフォルトの動作を無効化する(標準)
	// ------------------------------------------------------------
	e.preventDefault();
});
 
■アタッチイベントについて
 
アタッチイベントは、Internet Explorer 6 ~ 10 で利用可能です。
 
Internet Explorer 11 以降では廃止されました。
 
登録するコールバック関数は、必ず「IE 独自の仕様」で動作します
 
Legacy Event については、こちらで解説しています。
 
アタッチイベントは、IE5 Quirks モードでも動作します。
 
コンテキストメニューの表示をキャンセルする

(function(){

	// ------------------------------------------------------------
	// リスナーの登録場所(イベント伝達中における現在の場所)
	// ------------------------------------------------------------
	var current_target = document;

	// ------------------------------------------------------------
	// コンテキストメニューが表示される直前に実行されるイベント
	// ------------------------------------------------------------
	current_target.attachEvent("oncontextmenu",function (e) {

		// ------------------------------------------------------------
		// イベントの発生場所
		// ------------------------------------------------------------
		var target = e.srcElement;

		// ------------------------------------------------------------
		// 出力テスト
		// ------------------------------------------------------------
		console.log(current_target);
		console.log(target);
		console.log(e);

		// ------------------------------------------------------------
		// デフォルトの動作を無効化する(非標準)
		// ------------------------------------------------------------
		return false;
	});
})();

 
■イベントハンドラについて
 
最も複雑なのが、イベントハンドラです。
 
ドキュメントモードのバージョンによって、イベントの仕様そのものが切り替わります。
 
ドキュメントモードが 9 以降である場合、「標準的な仕様」で動作します
 
ドキュメントモードが 8 以前である場合、「IE独自の仕様」で動作します
 

■「互換モード」動作時の「ドキュメントモード」の値について

 
■Internet Explorer 9 以前の場合
 
「互換モード」で動作している場合、ドキュメントモードは、5 となります。
 
Internet Explorer 8 から対応しているはずの、ほとんどの API が利用できせん。
 
■Internet Explorer 10 以降の場合
 
「互換モード」で動作している場合、ドキュメントモードは、最新となります。
 
ただし「IE5 Quirks モード」なら 5 となります。
 
「互換モード」動作中でも、対応している API は、すべて利用可能です。
 
「Internet Explorer 10 以降」で、「特定の標準モードで動作させる <meta> タグの指定が無い」場合、イベントハンドラは、標準的な仕様で動作するでしょう。
 

■イベントハンドラの互換性について

 
■イベントハンドラの「IE独自の仕様」について
 
イベントハンドラの「IE独自の仕様」は、アタッチイベントと同じではありません。
 
登録したコールバック関数の引数から、Event オブジェクトを得る事はできません。
 
かわりに、window.event プロパティを使用します。
 
イベントハンドラの場合、コールバック関数内の this は、リスナーの登録場所です。
 
アタッチイベントの場合、コールバック関数内の this は、Window オブジェクトです。
 
■互換性を考慮してイベントハンドラを利用する
 
「標準的な仕様」と「IE独自の仕様」の2つを吸収する、複雑なコールバック関数を用意します。
 
コンテキストメニューの表示をキャンセルする

// ------------------------------------------------------------
// コンテキストメニューが表示される直前に実行されるイベント
// ------------------------------------------------------------
document.oncontextmenu = function(e) {

	// ------------------------------------------------------------
	// イベントオブジェクトを取得する(IE独自)
	// ------------------------------------------------------------
	if(!e) e = window.event;

	// ------------------------------------------------------------
	// リスナーの登録場所(イベント伝達中における現在の場所)
	// ------------------------------------------------------------
	var current_target = e.currentTarget || this;

	// ------------------------------------------------------------
	// イベントの発生場所
	// ------------------------------------------------------------
	var target = e.target || e.srcElement;

	// ------------------------------------------------------------
	// 出力テスト
	// ------------------------------------------------------------
	console.log(e);
	console.log(current_target);
	console.log(target);

	// ------------------------------------------------------------
	// デフォルトの動作を無効化する
	// ------------------------------------------------------------
	if(e.preventDefault){
		// デフォルトの動作を無効化する(標準)
		e.preventDefault();
	}else{
		// デフォルトの動作を無効化する(非標準)
		return false;
	}
};
 
■イベントハンドラの仕様を回避する
 
イベントハンドラを使わずに、イベントリスナーとアタッチイベントだけを利用すれば、ドキュメントモードのバージョンによる、仕様の切り替わりを考慮する必要はありません。
 
イベントリスナーに登録したコールバック関数は、必ず「標準的な仕様」で動作します。
 
アタッチイベントに登録したコールバック関数は、必ず「IE独自の仕様」で動作します。