今日はIE7 Beta2のJavaScriptにおいてimgの大きさや位置を変更するときにエラーとなる件を調べてみました。
どうもdocument.body.clientWidthやdocument.body.clientHeightの値が取得できないのが原因のようです。いろいろ調べたところ、以下のような現象を確認しました。
現象1
例えば、以下のページではbodyのonload時にalertでページの幅を表示するようにしていますが、これは0と表示されます。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> </head> <body style="overflow: hidden" onload="alert(document.body.clientWidth)"> <div id="a"></div> </body> </html>
この例で、
- style="overflow: hidden"を消す
- <div id="a"> </div>などと<div>要素の間に何か入れる
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">の部分を消す
のどれをしてもちゃんと幅が表示されます。つまり
- bodyのスタイルでoverflow: hiddenとし、
- かつ、何も含まないdiv要素が存在し
- かつ、DOCTYPE宣言でXHTML 1.0 Strictとしている
の場合に起こるということです。特にDOCTYPEが絡んでいることから、なんとなく例の標準モードと互換モードの違いによるものという気がします。
6/1追記
こちらのページに解決案がありました。やっぱし標準/互換モードでした。IE6で動いていたのはたまたまだったのかもしれません。とりあえず、document.body.clientWidth、document.documentElement.clientWidth、window.innerWidth。それぞれが値を持つ場合に分けて取得するようにしました。
現象2
元々上記現象が起こるのを発見したページですが、上に書いた内容とはちょっと違って3つのdiv要素があり、その中にはimgや文書が入っています。それでもdocument.body.clientWidtの値が取得できません。div要素それぞれにposition: absoluteを指定していますが、このうち最後の1つでposition: absoluteをやめるとdocument.body.clientWidthが取得できることがありました。どんな場合にこうなるのかわかりにくく再現方法が不明のため、これ以上追求できそうにありません。
現象3
overflow: hiddenを指定していてもスクロールバーが見えることがあります。
以上です。今回のもやっぱりCSSと、標準/互換モードの関係が肝っぽいです。これ以上は自力で解決できそうにありませんので、この辺にしておきます。