SafariとChromeの判別があやしくなったので改善してみる2011年08月25日 20時10分51秒

夏も終わり間近というこのタイミングで今年最初のエントリになっちゃうんだけども、デスクトップ版Safariが5.1になったことで以前書いた「SafariとChromeを判別してみる」の方法が通用しなくなっちゃったのであわてて更新してみる。ほんとは中華パッド3号とか4号とかのこと書きたかったんだけども。

前回のおさらい

前回のアプローチは、SafariとChromeでwindow.constructorが違っている(SafariはObject、ChromeはDOMWindow)ことを利用してこんなアプローチをしてた。

// Safariはtrue、Chromeはfalseを返す関数
<script type="text/javascript">
window.check1 = function() {
  try {
    return window.constructor.prototype.alert == undefined;
  } catch(e) {
    // IEとかエラーでるし。
    alert(e.message || e.description);
  }
}
</script>

<button type="button" onclick="alert(check1())">check1</button>

ところが、Safari5.1からはwindow.constructorがDOMWindowConstructorとやらに変わっちゃったので、Chromeと判別されちゃう。さて、困りました。

Safari Developer Libraryを探したら

んで、急いでAppleのSafari Developer LibraryDocument Additions Referenceプロパティを確認したところ、「webkitCurrentFullScreenElement」「webkitFullScreenKeyboardInputAllowed」「webkitIsFullScreen」なんてのが見つかった。

念のためChromeのJavaScriptコンソールで「document.webkit」まで入力してタブキーで候補をさらってみたところ「Current~」とか「FullScreen~」、「Is~」とかは表示されなかったのでなんとなくで「webkitIsFullScree」を採用することに決定。

ただし、プロパティの名前からしてbooleanを返すだろうから、単純に

!document.webkitIsFullScreen

なんて試しても判別がつかないので、undefinedかどうかをテストすることにして、こんな感じに。
<script type="text/javascript">
window.check2 = function() {
  try {
    return window.constructor.prototype.alert == undefined ||
           document.webkitIsFullScreen !== undefined;
  } catch(e) {
    return e.message || e.description;
  }
}
</script>

<button type="button" onclick="alert(check2())">check2</button>

で、こうなりました。

この変更を適用すると、こんな感じに。前回同様is_webkitとis_mobileの判定が出来る前提で。

<script type="text/javascript">
// Safariかどうか
window.is_safari2 = (function() {
    // WebKitじゃなきゃ当然Safariじゃないわな
    if(! window.is_webkit) return false;
    if(window.is_mobile) {
        // モバイル版の場合、SVGをサポートしてたらSafari
        return !! window.SVGColor;
    } else {
        // デスクトップ版の場合、windowコンストラクタのプロトタイプで判別
        try {
            // * ココ修正!! *
            // どっちかtrueならSafari
            return window.constructor.prototype.alert == undefined ||
                   document.webkitIsFullScreen !== undefined;
        } catch(e) {
            // そもそもwindow.constructor とか そのプロトタイプにアクセスできない
            // ブラウザもあるので try - catch しとく
            return false;
        }
    }
})();

// Chromeかどうか
window.is_chrome2 = (function() {
    // WebKitじゃなきゃ(ry
    if(! window.is_webkit) return false;
    // 後は基本的にSafariと逆
    if(window.is_mobile) {
        return ! window.SVGColor;
    } else {
        try {
            // * ココ修正!! *
            return window.constructor.prototype.alert != undefined &&
                   document.webkitIsFullScreen === undefined;
        } catch(e) {
            return false;
        }
    }
})();

</script>

<button type="button" onclick="alert(window.is_safari2)">Safariっすか?(改)</button>
<button type="button" onclick="alert(window.is_chrome2)">Chromeっすか?(改)</button>

Chrome 13まではこれで大丈夫だけど、フルスクリーンがどうのこうのなんて機能はOS X Lion向けっぽいのでいずれこれでも判別できなくなっちゃいそうではあるが。

つか、そろそろ中華パッドネタ書いときたいなぁ。もうすでに旬をすぎちゃってるんだけども。

追記

Safari且つChromeとか判定されたり、前回の記事と同時に表示すると上書きされちゃったりなど細々と考慮漏れがあったりしたのでちくちく修正してました。もう平気かな。

追記2(2011.12.28)

ありゃ、気付いたらChromeもdocument.webkitIsFullScreenとかサポートしちゃってるしorz さて、どうするべ…

→ window.chrome が使えそう。なぜこれに気付かないし。

コメント

_ rika-t ― 2012年02月11日 21時57分35秒

navigator.userAgentを使うと楽だと思いますよ。
見当外れだったらすみません。

_ dara-j ― 2012年02月13日 14時33分21秒

rika-tさん、コメントありがとうございます。
UA使って判定しないのは単に好みの問題ですw UA偽装まで考慮する必要ないのはわかってるんですけど…

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://dara-j.asablo.jp/blog/2011/08/25/6070926/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。