jQuery時代に生きるクロスブラウザ対応の知恵 8選

Auto Copyが移植されたらchromeへの移行を検討します。agoです。

jQueryを使用するようになってクロスブラウザを意識することは少なくなりましたが、それでもjQueryではカバーしきれない差異はそれなりにあります。

そこでjQueryを使っていてもはまる可能性の高いクロスブラウザのtipsをご紹介したいと思います。

1 Objectリテラル内の末尾カンマ

{ 'key' : 'val', }

上記のコードはIE6でエラーが出ます。

o = { ‘key’ : ‘val’, };

この動作はjavascriptの仕様からするとIE6の動作が正しく、本来であれば末尾のカンマは記述できません。 これは他言語でJSONを扱う場合でもエラーになるので注意してください。

また、Arrayの場合、Fxは上記と同じく要素が存在しないものと認識しますが、IE6は未定義値が定義されていると解釈され、ブラウザによって要素数が変わるので注意してください。

[1, 2, 3, ];
// Fxでは[1, 2, 3]と解釈され.lengthは3となります 
// IEは[1, 2, 3, undefined]と解釈され.lengthは4となります 

alert([1, 2, 3, ].length);

末尾のカンマは使わないように注意しましょう。

2 console object

IE6には標準でconsole objectが存在しません。

当然といえば当然なんですが、デバッグ用のコードが混ざっていた場合IEでは動作しなくなるので注意しましょう。

念のため以下のようなコードを先頭に記述しておくと安全かもしれません。

if (!window.console) window.console = { 'log' : function () {} };

3 文字列の末尾を取る

以下のコードはFxは「r」が表示されますが、IE6ではundefinedが表示されます。 (IE8は「g」が表示されます)

var str = 'str';
alert(str[str.length - 1]);

var str = ‘str’;alert(str[str.length - 1]);

また、以下のコードの場合、Fxでは「r」が表示されますが、IE6,8では「str」が表示されます。

var str = 'str';
alert(str.substr(-1));

var str = ‘str’;alert(str.substr(-1));

以下のコードであればFx,IEともに正しく「r」を取得できます。

var str = 'str';
alert(str.slice(-1));

var str = ‘str’;alert(str.slice(-1));

4 IEでサポートされないhtmlの記述

IE6は以下のものをサポートしません

  • optionタグのdisabled属性
  • select, iframe, flash(object, embed)のz-index (select boxはiframeの中に入れることで背景にすることも可能です。また、flashはwmodeの値によって背景化が可能です)
  • position : fixed (IE7,8もdoc typeが互換モードの場合、動作しません)

5 コメントに日本語があった場合の文字コード認識失敗時の挙動

以下のようにscript tagのsrcでjavascriptを読み込んだ場合、ソースファイルの文字コードを誤認するとエラーが発生することがあります。

<script type="text/javascript"/js/hoge.js"></script>

この誤認時の動作がブラウザにより違い、ブラウザによってまったく違う位置でエラーが発生したり、たまに正常に動いたりと検証が難しくなります。

  • ブラウザによってエラーの位置が違う
  • 日本語コメントの有無によってエラーが発生したりしなかったりする
  • コメント内の記述によりエラーの位置が変わる

と言った場合は文字コードを疑ってみてください。

この問題は行コメント(//)で発生しやすいので、日本語の書かれた行コメントの末尾には半角スペースを入れておくことをお勧めします。

また、script[charset]を指定することで、読み込みもとのhtmlの文字コードによらずJSの文字コードを正しく認識させることが可能です。

<script type="text/javascript" charset="utf-8"/js/hoge.js"></script>

6 .replace()の第二引数

IEは'‘.replace(’‘, ’$$‘)で「$$」が返りますが、IE以外は「$」が返ります。

これは「$1」といった場合のエスケープのためで、本来「$」が返るのが正しいのですが、一見IEの動作のほうが正しく見えるので注意しましょう。 replace - MDC

alert(‘’.replace(‘’, ‘$$’));

これを回避するにはIE以外の場合のみ第二引数に.replace(/$/g, ‘$$$$’)をかけるか(ここでも「$」がエスケープされます)、第二引数でfunction () { return ‘$$’ }のようにfunctionを指定すれば回避できます。

alert(‘’.replace(‘’, function () { return ‘$$’; }));

これは変数を指定している場合でも同じような動作になるので注意してください。

var dollar = ‘$$’;alert(‘’.replace(‘’, dollar));

7 IME on時のkeyevent

IE,safariではIME onの状態でもkeyupでキー入力が取得できますが、FxはIME onの状態ではkeyupが発行されず、代わりにtextイベントが発行されます。

event式autoKana.jsの紹介

FFのtext eventに関して

8 DOMに追加されていないa tagのhref

IE6は$(‘<a href="/"></a>’).attr(‘href’);で「/」が取得できません。

jQueryはIE6の.getAttribute()でフルパスが取得できない問題の対応を行っていますが、IE6は.innerHTMLに追加した時点で/をhttp://からのパスに書き換えているらしく、.innerHTMLでhtml elementを構築しているjQueryは$(‘<a href="/"></a>’)の時点で「/」が取得できなくなってしまっています。

alert($(‘’).attr(‘href’));

$(‘<a></a>’).attr(‘href’, ‘/’);ならIE6も正常に「/」を取得できるので、どうしても回避したい場合、こちらの方法を使用しましょう。

alert($(‘’).attr(‘href’, ‘/’).attr(‘href’));

手元の環境の都合でIE6,8, Fx3.5でのみ確認しています。

細かい点を上げればきりがないんですが、主立ったものをあげてみました。

カヤックではIE6も好きになれる技術者を募集しています!