IE6でposition:fixedがうまくいかないのをfixするhtc
to-Rの西畑さんの講演を聞いてIE6でpositonfixedが動かないのを思い出した。それでそれをどう回避するかというと以下みたいにwindow.onscrollのイベントが発生したときに毎回毎回位置を計算して描画する。このコードって実は問題で描画がスクロールの速度においつかずちらつきが発生したりする。
このちらつきは僕は苦手というエントリーを以前書いた(http://d.hatena.ne.jp/shogo4405/20060919/1158664960)そこにはstyle.setExpressionを使えばちらつかなくていいとも書いた。
といわけで
今回はHTML Component(.htc)を使って書き直してみる。以下の部分をfixed.htcみたいな名前にして保存する。あとはスタイルシートのbehaviorで読み込みするだけ。
<public:component> <attach event="ondocumentready" handler="fixed" /> <script type="text/javascript"> function fixed() { var i, expression = ''; var value, style = element.style; var currentStyle = element.currentStyle; if(currentStyle.position.toLowerCase() != 'fixed'){ return; }; var bounds = { Top : currentStyle.top, Right : currentStyle.right, Bottom : currentStyle.bottom, Left : currentStyle.left }; style.position = 'absolute'; for(i in bounds) { value = bounds[i]; expression = ''; if(bounds[i] == 'auto'){ continue; }; switch(i) { case 'Bottom': i = 'Top'; value = '-' + bounds.Bottom; expression = 'parseInt(document.documentElement.clientHeight) - '; expression += parseInt(currentStyle.height) + ' + '; break; case 'Right': i = 'Left'; value = '-' + bounds.Right; expression = 'parseInt(document.documentElement.clientWidth) - '; expression += parseInt(currentStyle.width) + ' + '; break; }; style.setExpression ( i.toLowerCase(), '(parseInt(document.documentElement.scroll'+ i + ') + ' + expression + parseInt(value) + ')' + ' + "px"' ); }; style.behavior = null; style = currentStyle = null; }; </script> </public:component>
使い方は以下のようにスタイルシートを記述。
<style type="text/css"> #fixed { position: fixed; top: 100px; left: 100px; behavior: url('fixed.htc'); /* ←今回はここがポイント */ } </sytyle>
注意として
上のコードでは互換モードでは動作しない。あと試作品。ソースが汚いので訂正する。あとIE7でもこのコードが動作してしまう。
今後の予定
バグとりしてライブラリとして公開します。