はじめに
JavaScriptは、本来スクリプトコードを一つ書けば、JavaScriptに対応したブラウザであれば、どのブラウザでも同じように動くはずです。しかし、現実にはそう簡単に行かず、あるブラウザではスクリプトが動くのに、別のブラウザではうまく動かない、といった事態がよく発生します。
これは、ブラウザのバージョンによって、サポートしているJavaScriptのバージョンに違いがあったり、たとえ同じバージョンのJavaScriptをサポートしていても、ブラウザごとにJavaScriptの実装に微妙な違いがあったりするためです。
このような、ブラウザの種類やバージョン、各々のブラウザ独自の実装の違いを考慮して、同じように動作するスクリプトを、クロスブラウザスクリプトと言います。クロスブラウザスクリプトを作るのには、ちょっとしたテクニックが必要となります。しかし、いったんテクニックを取得すると、クロスブラウザスクリプトを作る事は、それほど大変ではありません。
クロスブラウザスクリプトを作るためのテクニックには、大ざっぱに見て次なようなものがあります。
- ブラウザの種類を調べ、処理を振り分ける。
- ブラウザの種類とバージョンを調べ、処理を振り分ける。
- ブラウザがそのJavaScriptをサポートしているかどうかを調べ、処理を振り分ける。
実際には、これらのテクニックを単体で、あるいは組み合わせて使うことによって、クロスブラウザスクリプトを実現していくことになります。
これから、クロスブラウザスクリプトを実現するためのテクニックについて、色々と解説していきたいと思います。その中で今回は、ブラウザによって実装が異なるもっとも顕著な例として、Internet Explorerと、Mozilla系ブラウザ(FirefoxやNetscape Navigatorなど)のevent
オブジェクトの実装の違いと、それを考慮したクロスブラウザスクリプトの作成方法を紹介したいと思います。
ブラウザによるイベントの取り扱いの違い
event
オブジェクトは、JavaScript 1.2から追加されたオブジェクトで、Internet Explorerでは、バージョン4以降、Mozilla系ブラウザでは、Netscape Navigatorのバージョン6からサポートされています。
それ以前のJavaScriptでは、特定のHTMLタグ内に設定したイベントハンドラからしか、イベントを取得できませんでした。しかし、event
オブジェクトを使うことによって、ブラウザのコンテンツ表示領域のどこからでもイベントを取得できるようになり、その結果、ウェブページの表現の幅は劇的に広がることとなりました。
しかし困ったことに、Internet ExplorerとMozilla系ブラウザでは、event
オブジェクトの実装に微妙な違いがあります。細かく言うと、イベントの取得方法に関しては、Internet Explorerも、FirefoxなどのMozila系ブラウザも同じです。しかし取得したイベントから、イベントが持つ情報をとりだす方法には違いがあるのです。
それでは、何はともあれ、まずはInternet ExplorerとMozilla系ブラウザそれぞれの、event
オブジェクトを使ったスクリプトを見てみましょう。このスクリプトでは、まずブラウザ表示領域内でマウスボタンが押された時をイベントとし、関数の処理を発生させています。そして、関数内の処理で、イベントが発生したブラウザ表示領域内左端からの位置(X座標)と上からの位置(Y座標)を、警告用のダイアログボックス内に表示するようにしています。
<script type="text/javascript"> <!-- function eve() { alert ( "イベントが発生したX座標:" + window.event.offsetX + "\n" + "イベントが発生したY座標:" + window.event.offsetY ) return true; } document.onmousedown = eve; //--> </script>
<script type="text/javascript"> <!-- function eve(e) { alert ( "イベントが発生したX座標:" + e.pageX + "\n" + "イベントが発生したY座標:" + e.pageY ); return true; } document.onmousedown = eve; //--> </script>
それでは次に、それぞれのスクリプトの違いに目をむけていきましょう。
Internet Explorer、Mozilla系ブラウザともブラウザのコンテンツ表示領域内から、イベントを取得する方法は同じで、その用法は次の通りです。
document.取得するイベントタイプ = 関数 | スクリプト
サンプルの場合、8行目の「document.onmousedown = eve;
」の部分がそれにあたります。そしてここでは、マウスボタンが押された時、関数「eve
」を発生させています。この関数の処理は、それぞれのサンプルの3行目~7行目となります。
さて次に関数の処理で、event
オブジェクトからイベントが発生した位置に関する情報を取り出す方法です。しかし、ここからInternet ExplorerとMozilla系では違いが出てくることになります。
Internet Explorerの場合、通常のプロパティの指定と同様に、次の用法でイベントに関する情報を取り出すことができます。
window.event.プロパティ
また、Internet Explorerの場合、イベントが発生したブラウザ表示領域内左端からの位置(X座標)の値はoffsetX
プロパティが、上からの位置(Y座標)の値はoffsetY
プロパティがそれぞれ持っているので、それぞれの値は次のようにして取得することができます。
window.event.offsetX window.event.offsetY
しかしMozilla系ブラウザの場合、イベントに関する情報は、次のように一旦変数に代入し、その変数からとり出す事になります。
変数.プロパティ
サンプルの場合、イベントに関する情報は、3行目で「function eve(e)
」として、変数「e
」に代入しています。さらに、プロパティ名もInternet Explorerとは違い、イベントが発生したブラウザ表示領域内左端からの位置(X座標)の値は、pageX
プロパティ、上からの位置(Y座標)の値はpageY
プロパティとなります。
これらによりサンプルの場合、それぞれの値は次のようにして取得することになります。
e.pageX e.pageY
Internet ExplorerとMozilla系ブラウザを判断する
以上見てきた通り、Internet ExplorerとMozilla系ブラウザには、event
オブジェクトの実装に、微妙な違いがあります。次の段階として、クロスブラウザスクリプトを作る場合、この実装の違いを考慮してスクリプトを記述することになります。
前述の通り、クロスブラウザスクリプトを実現するためには、いくつかの方法があります。その中で今回は、ブラウザを判断し、Internet ExplorerではInternet Explorer用の、Mozilla系ブラウザ(Netscape NavigatorやFirefoxなど)では、Mozilla系ブラウザ用のスクリプトを実行する方法を使ってみましょう。
ブラウザの判断は、navigator
オブジェクトのappName
プロパティを調べて行うことができます。appName
プロパティは、Internet Explorerの場合「Microsoft Internet Explorer」の値を、Mozilla系のブラウザの場合「Netscape」の値を持っています。つまりappName
プロパティの値の先頭の文字列が「M」であった場合、それはInternet Explorer、「N」であった場合は、Mozilla系ブラウザであると判断することができます。
appName
プロパティの一番先頭の文字列は、String
オブジェクトのcharAt
メソッドを使って「navigator.appName.charAt(0)
」とする事によって、とり出すことができます。
これを利用して次の用法を使えば、Internet Explorerのみで実行されるスクリプト、Mozilla系ブラウザで実行できるスクリプトを設定することができます。
if(navigator.appName.charAt(0)=="M"){ ''Internet Explorerでのみ実行されるスクリプト'' } if(navigator.appName.charAt(0)=="N"){ ''Mozilla系ブラウザでのみ実行されるスクリプト'' }
後は、「Internet Explorerでのみ実行されるスクリプト」の部分に、Internet Explorerのevent
オブジェクトの用法を使ったスクリプトを、「Mozilla系ブラウザでのみ実行されるスクリプト」の部分にMozilla系の用法を使ったスクリプトを設定すればいいです。
そして完成したスクリプトは、次のようになります。
<script type="text/javascript"> <!-- function eve(e) { if(navigator.appName.charAt(0)=="M"){ alert ( "イベントが発生したX座標:" + window.event.offsetX + "\n" + "イベントが発生したY座標:" + window.event.offsetY ) return true; } if(navigator.appName.charAt(0)=="N"){ alert ( "イベントが発生したX座標:" + e.pageX + "\n" + "イベントが発生したX座標:" + e.pageY ); return true; } } document.onmousedown = eve; //--> </script>
これにより、Internet Explorerでこのスクリプトを実行した場合は、4行目~8行目までの、Mozilla系のブラウザで実行した場合は、9行目~13行目のスクリプトが実行されることになります。
Internet Explorer、Mozilla系ブラウザ以外のブラウザの対応
さて、ここまでは、Internet ExplorerとMozilla系ブラウザで、同じように動くスクリプトを記述する方法を見てきました。しかし現実には、これらのブラウザだけを考慮しただけでは、まだ十分とは言えません。
たしかに、現在のブラウザのシェアを考えた場合、Internet ExplorerとMozilla系ブラウザを考慮すれば、ほぼ100%に近いブラウザをサポートしたことになるかもしれません。しかしながら、本当の意味でのクロスブラウザスクリプトを作る場合、Internet ExplorerとMozilla系ブラウザ以外のブラウザのことも考慮したスクリプトを作ることを、目指すべきでしょう。またそれ以外にも、バージョンが古くevent
オブジェクトをサポートしていないブラウザに対しては、サポートしていないスクリプトからくるエラーが発生しないよう、配慮しなければいけません。
Internet ExplorerとMozilla系ブラウザ以外のブラウザで、event
オブジェクトをサポートしているブラウザには、OperaとSafariがあります。そしてOperaとSafariは、Internet Explorer、Mozilla系ブラウザ両方の、event
オブジェクトの用法をサポートしています。
また、appName
プロパティの値として、Operaの場合「Microsoft Internet Explorer」の値を、Safariの場合「Netscape」の値を持っています。このため、「Sample_3.html」のスクリプトを実行した場合、Operaは、4行目~8行目までのInternet Explorer用のスクリプトが、Safariは、9行目~13行目のMozilla系ブラウザ用のスクリプトが実行されることになります。しかしながら、両ブラウザともそれぞれのevent
オブジェクトの用法がサポートされているため、スクリプトは、問題なく実行されます。つまり今回の場合、「Sample_3.html」のままで、Opera、Safariの両ブラウザともサポートしていることになります。
また、バージョン4以前のNetscapeなど、event
オブジェクトをサポートしていないブラウザでは、「document.取得するイベントタイプ = 関数
」の用法で、イベントを取得すること事自体ができないので、エラーは発生しません。
まとめ
今回は、クロスブラウザスクリプトが、どのような時に必要で、どのようにして実現するか、だいたいの感じを見てもらうために、サンプルを上げて解説しました。
本来、JavaScriptは、Javaと同じように、一つのスクリプトを書けば、JavaScriptをサポートしたブラウザであれば、同じように動くべきです。しかしながら、今回紹介したevent
オブジェクトのように、なかなか理想通りにいかないのが現実です。そのような時に必要となるのが、クロスブラウザスクリプトのテクニックなのです。