打印

SD9014: IE 标准模式中 BODY 元素的高度变化和 IE6(S) 中 BODY 元素的宽度变化会触发 window.onresize 事件

作者:陆远 孙东国

标准参考

Mozilla Developer Center 对 window.onresize 的描述如下,窗口 resize 事件的事件句柄。resize 事件在窗口大小变化时触发。并非规范的一部分。

MSDN 中 onresize 是一个许多对象均支持的事件,onresize 在对象的尺寸将要变化时被触发。IE 中 onresize 不仅可以应用于 window 对象,还可以应用于各种拥有布局(触发了hasLayout属性)的元素对象上。

关于 onresize 的详细信息,请参考 https://developer.mozilla.org/En/DOM/Window.onresizehttp://msdn.microsoft.com/en-us/library/ms536959(VS.85).aspx

window.onresize 虽然不是 W3C 规范中的事件,但已被目前各主流浏览器所支持。

问题描述

IE 标准模式下 BODY 元素的高度发生变化时就会触发 window.onresize 事件。

造成的影响

在标准模式下,IE 对 onresize 事件的特殊支持可能导致作者由于动态改变了某个元素的尺寸而使 BODY 元素的尺寸也发生了变化,从而触发了 window.onresize 事件,但此时浏览器的窗口并没有改变大小。其他浏览器则不会触发 window.onresize 事件。

这种事件触发差异可能会造成兼容性问题。

受影响的浏览器

IE6(S) IE7(S) IE8(S)  

问题分析

分析以下代码:

<!DOCTYPE html>
<html style="border:5px solid blue;">
<head>
</head>
<body style="border:5px solid green;">
<div id="d" style="background:gray; height:30px;"></div>
<div id="e" style="background:lightgray;">Test line</div>
<script>
    var d = document.getElementById("d");
    var c = 0;
    setInterval(function () {
        c = parseInt(Math.random() * 100);
        d.style.height = c + "px";
    }, 1000);
    window.onresize = function () {
        d.innerHTML = d.style.height;
    }
</script>
</body>
</html>

测试代码中 BODY 元素下有两个 DIV 元素【d】和【e】,设置了一个定时器每隔 1 秒设置一次【d】的 height 特性,设置的值为 0—99px 的随机数。

window.onresize 事件触发时,将【d】的 height 特性的值显示在【d】的内容上。

将测试代码中的 HTML 与 BODY 元素的 height 特性设置为 3 组不同的情况与运行的结果列表如下
OK 代表 window.onresize 被触发,FAIL 代表没有被触发):

  IE6(Q) IE7(Q) IE8(Q) IE6(S) IE7(S) IE8(S) Firefox Chrome Safari Opera
HTML: height:auto
BODY: height:auto
FAIL OK FAIL
HTML: height:100%
BODY: height:auto
FAIL OK FAIL
HTML: height:100%
BODY: height:100%
FAIL FAIL FAIL

在测试代码中,每隔 1 秒动态改变的是【d】的高度,从 window.onresize 事件触发条件上看应该与【d】的高度的改变没有关系,然而在 IE 标准模式中,【d】的高度的变化却触发了 window.onresize 事件。修改上述测试代码,对【d】的宽度每秒进行一次设置,结果显示在 IE6(S) 中【d】的宽度变化也会触发window.onresize 事件。

IE6(Q) IE7(Q) IE8(Q) 中,根元素为 BODY,且 BODY 元素高度始终为 100%。无论【d】如何改变高度,均不会影响 BODY 元素的高度,所以 window.onresize 没有被触发。

为 HTML 与 BODY 元素均设置为 height:100% 后,IE 标准模式下,这时【d】的高度的改变也不会影响到 BODY 元素高度的改变。所以 window.onresize 也没有被触发。而当 BODY 元素的高度不是100%,由于 BODY 子元素的高度变化导致了 BODY 自身高度的变化,IE 标准模式下就会触发 window.onresize,虽然这时浏览器的窗口的大小并没有发生变化。

解决方案

1. 不期望触发 window.onresize 事件时:

为 HTML 与 BODY 元素设置 height:100% 和 width:100% 以防止因为其尺寸变化而触发 window.onresize 事件,如上表中第三行。

2. 期望触发 window.onresize 事件时:

在非 IE 浏览器中,主动去触发一次 window.onresize 事件,代码如下:

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("resize", true, true, this, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
window.dispatchEvent(evt);

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6
Chrome 5.0.342.2 dev
Safari 4.0.4
Opera 10.50
测试页面: window_onresize.html
本文更新时间: 2010-06-24

关键字

window resize 大小 窗口 BODY