私も最近はレスポンシブ案件を受けることも多くなってきていまして、レガシーIEに対応する際は個人的な経験からRespond.jsを使用しています。(masonry.jsを実験した時にcss3-mediaqueries.jsは問題があった)
PCサイズの時だけにjQueryのプラグインを適用したい、といった状況で、ブレークポイントに合わせてJavaScriptを発火する必要があったのですが、どうもIE8だけブレークポイントが違っているので調べてみました。
ブラウザのさまざまなサイズを取得する
これまでサイズ取得には、もはや何のためのハックなのかわからない
document.clientWidth || document.documentElement.clientWidth
といったコードを使っていたのですが、ここで一度、ブラウザのサイズを取得する方法を整理したいと思い、ちょっとしたツールを組んでみました。
Macではブラウザに枠がなく、スクロールバーも浮いているためほとんどのプロパティが同じ数値になります。問題になるのはWindows、特にIEのバージョン間での違いですね。
最近の環境では以下のようなプロパティが有効な模様です
(1)ブラウザ枠の外側の幅と高さ
window.outerWidth
/window.outerHeight
※IEはバージョン9以上
(2)ブラウザ枠の内側の幅と高さ
window.innerWidth
/window.innerHeight
※IEはバージョン9以上document.documentElement.offsetWidth
/document.documentElement.offsetHeight
(3)表示領域の幅と高さ(スクロールバーを含まない)
document.documentElement.clientWidth
/document.documentElement.clientHeight
※html要素document.body.clientWidth
/document.body.clientHeight
※body要素document.clientWidth
/document.clientHeight
※検索するとdocument.width
/document.height
というプロパティをちらほら見かけますが非推奨です(Gecko6.0よりサポート外)。
スクロールバーがない場合、(2)と(3)は同じになるはずですが、IE8では上下左右に2pxの謎の枠があるため微妙に値が異なっています。IE7にも謎の枠があります。こちらはスクロールバーがあろうがなかろうが同じ値になっています(爆
これらを踏まえてRespond.jsにおけるIE8のブレークポイントについて見てみます。
ブレークポイントの違い
見た感じモダンブラウザでは
window.innerWidth
/ window.innerHeight
が基準になっているようです。 IE8ではこのプロパティは存在しないですが
document.documentElement.offsetWidth
/ document.documentElement.offsetHeight
で代用することができます。
なので、これを使えばいいかというと、そうはいかない我らがIEです。 Respond.jsはIE8においては
document.documentElement.clientWidth
/ document.documentElement.clientHeight
を見て切り替えているようです。(まあ、これはIEのせいではないですけど)
Respond.jsのソースを見るとの98行目で
var name = "clientWidth", docElemProp = docElem[name]...
となっているのは見えるのですが、ソース内にwindow.innerWidth
やdocument.documentElement.offsetWidth
は見当たりません。内部で<body>
タグをcreateElement
して使っているようなので、そのフェイク<body>
のサイズがIE8だと違っちゃうってことなんでしょうか。
結論として、IE8も含めてRespond.jsのブレークポイントと同期するには
window.innerWidth || document.documentElement.clientWidth
を監視すればよい、ということになります。
IE8ではブレークポイントが若干違ったままになりますが、今回の目的はメディアクエリーと同期してJavaScriptを発火することなのでそこのタイミングが同じでありさえすれば良いのです。
ブレークポイント自体を一致させるとなると、ソースをいじる必要がありそうです。
※互換モードとかは知りません