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="" /> タグを使用します。
しかし、余程の致命的な問題でも無い限りは、特定のバージョンの標準モードを指定すべきではありません。
将来的に該当するドキュメントモードのサポートが終了した場合、閲覧できなくなるかもしれません。
詳しい仕様は、MSDN が参考になります。
http://msdn.microsoft.com/ja-jp/library/cc288325.aspx (ドキュメント互換モードの指定)
イベントの互換性について
■イベントの互換性について
■イベントリスナーについて
イベントリスナーは、Internet Explorer 9 以降で利用可能です。
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 以降では廃止されました。
アタッチイベントは、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独自の仕様」で動作します。