jQuery.browserの実現方式


jQuery.browserの実現方式
jQueryのbrowserオブジェクト
jQueryのbrowserオブジェクトにはブラウザの情報が保存されています.クロスブラウザは、ほとんどのクライアントJSライブラリが備えなければならない基本的な特性であり、ブラウズのタイプとバージョン番号を判断してオブジェクトに保存するのは、異なるブラウザに対して異なるポリシーをとるためです.
次のコードはjQueryを示すために使用されます.browserの使い方:

<script type="text/javascript" src="jquery.js"></script>
<script>
document.write('$.browser.webkit: ' + $.browser.webkit + '<br />');
document.write('$.browser.opera: ' + $.browser.opera + '<br />');
document.write('$.browser.msie: ' + $.browser.msie + '<br />');
document.write('$.browser.mozilla: ' + $.browser.mozilla + '<br />');
document.write('$.browser.version: ' + $.browser.version);
</script>

このコードの異なるブラウザでの表示効果は異なります.
IEの表示効果は以下の通りです.

$.browser.webkit: undefined
$.browser.opera: undefined
$.browser.msie: true
$.browser.mozilla: undefined
$.browser.version: 8.0

$に基づいてbrowser.msieがtrueであるかどうかは,ブラウザがIEカーネルであるか否かを判断できる.$を通過する.browser.バージョンでは、ブラウザカーネルのバージョン番号を取得できます.他のブラウザでは同様の方法で判断できます.
実現構想.
  jQuery.browserの実現構想は以下の通りである.
  1. Windowsを通ります.navigator.userAgentブラウザの記述文字列の取得
  2. 正規表現を使用してマッチングすると、ブラウザカーネルによって正規表現が異なります.
  3. 一致した結果に基づいて、特定のブラウザかどうかを判断し、バージョン番号を抽出します.
  4. 結果をbrowserオブジェクトに保存します.
まず、異なるブラウザのwindowをテストしてみましょう.navigator.userAgentの出力結果:

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua);

Google Chromeの表示結果:

user agent:
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.60 Safari/534.24

CheomrのブラウザカーネルがWebkitであることを知っていますので、その中で最も重要なのはWebKitキーワードですが、Google Chromeは互換性を示すために記述文字列にMozillaなどの文字も含まれています.他のブラウザでも似たような状況があります.
Apple Safariの表示結果:

user agent:
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1

Microsoft IE 8.0の表示結果:

user agent:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)

Mozilla FireFoxの表示結果:

user agent:
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3

Operaの表示結果:

user agent:
Opera/9.80 (Windows NT 6.1; U; Edition IBIS; zh-cn) Presto/2.8.131 Version/11.10

ブラウザによって採用される正規表現が異なるため、以下、異なるブラウザの場合についてjQuery.browserの実装をさらに解析した.
Webkitカーネルの検出
Google ChromeとApple SafariはWebkitカーネルを使用しており、記述文字列にも「Webkit」が含まれているため、検出に使用する正規表現には「Webkit」が含まれる必要がある.
また、バージョン番号は「Webkit」のキーワードに続くもので、真ん中は「/」で区切られています.したがって、ブラウザがWebkitカーネルであるかどうかを次のコードで判断し、バージョン番号を抽出できます.

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /WebKit\/([\w.]+)/.exec(ua);
if (match) {
	document.write('Webkit Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not Webkit Kernal');
}

使用する正規表現は/WebKit/([w.]+)/で、「Webkit」および区切り記号「/」が含まれていることを示し、スペースまで「/」の後の文字をバージョン番号としてスナップします.(wアルファベットや数字や下線や漢字などにマッチします.)
IEカーネルの検出
IEカーネルブラウザの記述文字列には「MSIE」が含まれており、バージョン番号は「MSIE」キーワードに続いており、真ん中はスペースで区切られている.したがって、ブラウザがIEカーネルであるかどうかを次のコードで判断し、バージョン番号を抽出することができます.

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /MSIE ([\w.]+)/.exec(ua);
if (match) {
	document.write('IE Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not IE Kernal');
}

使用する正規表現は/MSIE([w.]+)/で、「MSIE」とスペースが含まれていることを示し、次のスペースまでスペースをキャプチャした後の文字をバージョン番号として使用します.
Mozillaカーネルの検出
Mozilla Firefox記述文字列には「Mozilla」が含まれており、バージョン番号は「rv:」の後に表示されます(Mozillaキーワードの後にバージョン番号もありますが、rvの後のバージョン番号はさらに細かくなります).したがって、ブラウザがMozillaカーネルであるかどうかを次のコードで判断し、バージョン番号を抽出できます.

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /Mozilla(?:.*? rv:([\w.]+))/.exec(ua);
if (match) {
	document.write('Mozilla Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not Mozilla Kernal');
}

使用する正規表現は、/Mozilla(?:.*?rv:([w.]+)/で、「Mozilla」が含まれていることを示し、次のスペースまでバージョン番号として「rv:」の後の文字をスナップします.
Operaカーネルの検出
Opera記述文字列には「Opera」が含まれており、バージョン番号は「Version/」の後に表示される(同様にOperaキーワードの後にバージョン番号もあるが、「Version」の後のバージョン番号はさらに細分化されている).したがって、ブラウザがOperaカーネルであるかどうかを次のコードで判断し、バージョン番号を抽出できます.

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /Opera(?:.*Version)\/([\w.]+)/.exec(ua);
if (match) {
	document.write('Opera Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not Opera Kernal');
}

使用する正規表現は、「Opera」が含まれていることを示し、次のスペースまでバージョン番号として「Version/」の後の文字をキャプチャして、「Version/」を含む文字を表します.
結合
以上の異なるブラウザに対するコードを直列に接続することでjQueryを実現することができる.browserになりました.しかし、jQueryの実装はもっとテクニック的です.以下は、jQueryの実装に近い書き方です.

$ = function() {
    function uaMatch(ua) {
        ua = ua.toLowerCase();

        var match = rwebkit.exec(ua)
                    || ropera.exec(ua)
                    || rmsie.exec(ua)
                    || ua.indexOf("compatible") < 0 && rmozilla.exec(ua)
                    || [];

        return {
            browser : match[1] || "",
            version : match[2] || "0"
        };
    }

    var
    rwebkit = /(webkit)\/([\w.]+)/,
    ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
    rmsie = /(msie) ([\w.]+)/,
    rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,    
    browser = {},
    ua = window.navigator.userAgent,
    browserMatch = uaMatch(ua);

    if (browserMatch.browser) {
        browser[browserMatch.browser] = true;
        browser.version = browserMatch.version;
    }

    return { browser: browser }
}();

このJSファイルを「jquery-browser.js」と名付け、htmlで参照します.

<script type="text/javascript" src="jquery-browser.js"></script>
<script>
document.write('$.browser.webkit: ' + $.browser.webkit + '<br />');
document.write('$.browser.opera: ' + $.browser.opera + '<br />');
document.write('$.browser.msie: ' + $.browser.msie + '<br />');
document.write('$.browser.mozilla: ' + $.browser.mozilla + '<br />');
document.write('$.browser.version: ' + $.browser.version + '<br />');
</script>

効果と直接参照jquery.jsは同じです.
いくつかの違いに注意しましょう.
  1. userAgentは小文字に変換されてマッチングされ、大文字と小文字の影響を回避した.
  2. Mozillaの判断にuaを追加しました.indexOf(「compatible」)<0は、Mozilla対応と主張するブラウザの影響(例えばIE 8.0)を排除するためであり、一部の検索エンジンの爬虫類もMozilla対応と主張することが多い.
  3. OperaとMozillaを検出する正規表現は「?」「rv」または「Version」があってもなくてもよいことを明記します.これは、異なるOperaとMozillaカーネルブラウザ(または古いバージョン)を互換化するためかもしれません.
  4.matchスナップのグループは2つあり、1つ目はブラウザカーネル名、2つ目はバージョン番号であり、ブラウザカーネル名とバージョン番号を同時に抽出し、コード量を減らすことができます.
以上jQuery.briwserの比較的完全な実現.主なテクニックはwindowを使うことです.navigator.userAgentは、ブラウザの記述文字列を取得し、正規表現によってその文字から情報を抽出します.