はてブロ@ama_ch

https://twitter.com/ama_ch

IEでoffsetHeightがとれないときの対処方法

ご無沙汰しています。
最近はもっぱら JavaScript ばかり書いているため、偽物臭がかつてないほど強くなっているあまちゃんです。実に1年半ぶりのエントリーです!


最近 IE8 で要素の offsetHeight が取得できなくて困ったので、その対処方法を書いておきます。


まず背景や問題の詳細。
やりたかったことは、

  • height に auto が指定されている div が沢山あり、現在の offsetHeight が最も大きいものにすべて揃える

ということです。


FF や Chrome では DOM 操作をするのと同じタイミングで描画もされ、描画後の任意のタイミングで element.offsetHeight の値を参照することができました。しかし IE では DOM を操作するコードの実行時に画面が描画されないようで、(コード上では)描画済みの要素の offsetHeight を参照しても、前者のブラウザとは違う値になってしまいました。
computedStyle や runtimeStyle でも取得できず。ムムム...


そこで id:teppeis 先生に教えてもらったのが setTimeout を使う方法。

var height = 0;
window.setTimeout(function() {
    height = element.offsetHeight;
}, 0);

なんでこれで取れるかっていうのはamachangのエントリーが分かりやすいです。
JavaScript を学ぶ際に一番重要なのに、誤解されがちな setTimeout 系の概念 - IT戦記


このままだと引数が渡せないのでこんな感じに。

var height = 0;
window.setTimeout(function(self) {
    height = element.offsetHeight;
}, 0, this);


しかし IE では setTimeout の3番目以降の引数はサポートされていなかった...

Internet Explorer では、最初の構文で関数に渡す追加のパラメータは動作しないことに注意してください。

window.setTimeout - MDC


IE で引数を渡すために結局こんな感じに。

var height = 0;
(function(self) {
    window.setTimeout(function(self) {
        // ここでselfが使える
        height = element.offsetHeight;
    }, 0);
})(this);


というわけで無事に IE でも offsetHeight がとれました(^o^)/

2010/10/2 追記

IE で offsetHeight がとれないのはこういう訳だったらしい。。。


@yo_waka先生ありがとうございました。