JavaScript、Ajax、HTML5(API)、Ruby…Web及び関連技術の実験&情報公開&制作物紹介。

非対応ブラウザでMooToolsを完全に無効にする方法

いきなり後ろ向きなエントリーでちょっと恐縮なのです(汗)

趣味の範囲を超えて『仕事』でMooToolsを使用していると、ブラウザの対応範囲の問題というモノには常に悩まされます。
具体的には、一番困るのが「古いブラウザにも対応して欲しい」というモノ。
それはなんとか説得できたとして、次に来るのが「じゃあ、せめて非対応ブラウザでエラーが出ないようにして欲しい」。

そこで、非対応ブラウザでエラーが出ないようにするMooToolsの微カスタマイズをお教えします。
と言っても、元のソースもロジックも触らず、ちょっとだけ書き加えるだけです。

0. MooToolsをダウンロード

まずは、MooToolsの準備。
サイトから、download を選択し、必要なオプションを選択してダウンロードします。

『Choose the Components you need』は、もちろん必要なモノだけでOKです。初めてでよく分からないという人は、全てにチェックを入れてしまえばOK。その際、下から順にチェックを入れると簡単です。コンポーネントの依存性がある場合、必要なコンポーネントにも自動的にチェックが入りますので。

ここで、ポイントは『Choose compression type』オプション。
クリックするとラジオボタン(のようにデザインされたオプション群)が表示されますが、一番上の「JavaScript Packer」を選択します(何もしていなければデフォルトで選択されていると思います)。
これを選択する理由は、「後の作業が一番分かりやすいから」。
以降、この「JavaScript Packer」オプションでダウンロードされたモノとして続けます。

0-1. MooTools1.2b1の場合

2007/11/22 現在、MooToolsの最新ベータ版 ver.1.2b1 が公開されています。
そちらのダウンロードページを見ると、『Choose compression type』オプションにまだ「JavaScript Packer」が用意されていません。
1.2b1 でかつPackerで圧縮されたモノを使用したい場合は、ご自分でDean Edwards Packerのサイトで圧縮してみてください。
ただし自己責任でお願いします。

1. .jsファイルの編集

(「JavaScript Packer」オプションでダウンロードした場合、).jsファイルをテキストエディタで開くと、中身はおおざっぱに以下のようになっています。

 1: //MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
 2: 
 3: eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};...(長いので以下省略)

1行目はライセンス表示、2行目は空行、3行目は、MooToolsのすべての(選択された)コンポーネントのコードを圧縮した長い1行(eval()1文)になっています。
この3行目の前と、3行目の後(=ファイルの最後尾)に、それぞれ以下の内容を挿入します。

(3行目の前)
if((window.ActiveXObject)||(document.childNodes&&!document.all&&!navigator.taintEnabled)||(document.getBoxObjectFor!=null)||window.opera)/*@cc_on @if (@_win32 && @_jscript_version > 5.5) @*/
(ファイル最後尾)
//@end

つまり全体として、以下のようになります。

 1: //MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
 2: 
 3: if((window.ActiveXObject)||(document.childNodes&&!document.all&&!navigator.taintEnabled)||(document.getBoxObjectFor!=null)||window.opera)/*@cc_on @if (@_win32 && @_jscript_version > 5.5) @*/
 4: eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};...(長いので以下省略)
 5: //@end

これで終わりです。
MooTools非対応ブラウザでは、MooToolsは一切機能しません。
この.jsファイルを使用すればOK、というワケです。

2. 非対応ブラウザでエラーを出さないスクリプト記述

上記のように加工した.jsファイルを使用すると、MooToolsを使用している前提で記述したスクリプトは、そのままだと非対応ブラウザだとエラーになってしまいます。(対応ブラウザなら問題ありません。)
そこで、エラーを出さないようにするためにもう一工夫。

MooToolsを使用したい箇所を、以下のようなif文ブロックで括ります。

if (window.MooTools) {
    // MooToolsの機能を利用したスクリプトの記述
}

これは、MooToolsが有効ならば、グローバルな変数(≒window オブジェクトに設定されたプロパティ)にMooToolsというオブジェクトが設定されるからです。
それが有効かどうかで、MooToolsが使えるかどうかを判別する、と言うわけです。

3. おまけ:技術情報

念のため、.jsファイル内に追記した記述がどのような意味なのかを簡単に解説。
これは実は、MooTools(v1.1x)内のブラウザ判別ルーチンをほぼそのまま拝借しているだけです。
興味のない方は読み飛ばしてください。

3行目のifの条件節は、「||」(論理和)で4つに別れます。
最初が「IEかどうか」、2番目が「Safari(およびそれと同じWebKitを利用したブラウザ)かどうか」、3番目が「Firefox、Netscape等のGeckoエンジンを利用したブラウザかどうか」、4番目は「Operaかどうか」(まんま)です。
2番目の「WebKitかどうか」についてのみ詳細。その中が更に「&&」で3つに別れます。
最初は「document.childNodes」が有効か(=DOMが有効か)。これはほとんどのモダンブラウザなら有効です。
一つ飛ばして3番目は、「navigator.taintEnabled が無効か」。
navigator.taintEnabled() というのは、「ユーザーに非通知でデータ送信が可能かどうか(データテイント機能の使用有無)を返すメソッド」です。「何それ?」て思われた方、ご安心ください。Netscape Navigator 3.x の時代の、古い古ーい仕様で、データテイント機能は現在使われておりません。多くのブラウザは、ただfalseを返すだけです。
ただしSafari(WebKit)では、このメソッドそのものを定義していません。よって「!navigator.taintEnabled が true」=「navigator.taintEnabled()が定義されていない」=「Safari(WebKit)」という判別になるのです。
じゃぁ2番目の「!document.all」は何なのか、というと。分かる方は分かると思いますが、「document.all」はIE固有のプロパティです。つまりこれはIEを除外するための記述です。(実際にはOperaも除外されてしまいますけれど)。
なぜこれが必要なのかというと、どうやらIEでは、後ろに「()」をつけない「navigator.taintEnabled」を記述すると「オブジェクトまたはプロパティは存在しません」というエラーになってしまうようなのです。それを避けるための記述、ということですね。
ただその前に「window.ActiveXObject」でIEかどうかは判別できているはずなので、やっぱりここでは要らないような気もしますけれど、一応、念のため付加してあります。

ifの条件節の後に続くコメントは、IE固有の「条件付きコンパイル」の記述です。
そういう前提で眺めてみれば大体分かると思いますので、さらっと。ここでは、「WindowsでかつIE5.5より上のバージョン(=WinIE6以上)」を判定しています。つまりWinIE5.5以下やmacIEを排除しています。
ちなみにファイル最後尾に追記した「//@end」は、この条件付きコンパイル内の「@if」に対応する「if文(ブロック)の終わり」を表しています。

4. 応用・発展性

今回は、私が実際に仕事で(必要に迫られて)書いたものですが、同じような記述を応用すれば、MooTools以外のJavaScriptライブラリ使用時にも流用・転用できると思います。
またMooToolsでも、理由があってPacker圧縮したものを使用できない(あるいはPackerが信用できない)という場合でも、ちょっと書き方を変えれば利用できるはずです。
例えば、追記する記述中の、3行目の最後尾(条件付きコンパイルコメントの終わりの「*/」の後)に「{」を、最終行の「//@end」の前に「}」を付ける↓

(3行目の前)
if((window.ActiveXObject)||(document.childNodes&&!document.all&&!navigator.taintEnabled)||(document.getBoxObjectFor!=null)||window.opera)/*@cc_on @if (@_win32 && @_jscript_version > 5.5) @*/{
(ファイル最後尾)
}//@end

これだけで、他の多くのパターン(特にPackerを使用できない/したくない場合)に応用できるはずです。
(ただし実験していないので、何か問題が起きても私は保証できかねますm(_ _)m)

カテゴリ

月別 アーカイブ

OpenID対応しています OpenIDについて

このブログ記事について

このページは、あんちもん2が2007年11月23日 14:21に書いたブログ記事です。

ひとつ前のブログ記事は「そろそろ……。」です。

次のブログ記事は「JavaScript-XPathのMooTools用プラグインを作成」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。