今日因为项目要求,需要用JS做一些弹窗效果,可以随着滚动条滚动。在IE6浏览器下,需要用到JS的HACK,于是从网上摘录了document.body的属性解释,用于IE6弹窗位置的控制,结果是在窗口最大化情况下一切都是好的,而在窗口还原,就是窗口缩小时,控制失效。我也查看了thickbox的代码,发现他是直接禁用IE6的滚动条来解决这个BUG的,就是说,thickbox的开发人员也没有找到很好的办法来解决这个问题,囧啊,真是囧啊~~~~!

不过在研究这个问题的时候,我却对document.body各属性有了更深的了解,而且发现了很多人忽略掉或者根本不会去考虑的问题

我花了一些时间去测试这些属性在不同浏览器和文档结构环境下的解释。

测试用的是一个页面内容为400×400的文件进行的,因为文件的文档格式会对document.body.scrollTop等属性有不同影响,请参考?id=64的解释,这里也用了这段代码,以使不同浏览器都能取到值。

我还测试了多种文档格式对这些属性的影响,这里用的文档格式是Transitional,我还测试了Strict和无格式时的情况。证实了Strict和Transitional对属性的解释是一致的,而无格式时就会有大不同。所以建议大家在设计时一定要加上文档格式。以下是测试的截图,分别是IE6,IE7,FF,OPERA在窗口最大化和缩小时(窗口还原到出现两个滚动条)的这些属性的值,以下是测试的文档和分析结果:

<br/><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br/><html xmlns="http://www.w3.org/1999/xhtml"><br/><head><br/><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><br/><title>无标题文档</title><br/><style type="text/css"><br/>body{margin:0;padding:0;font:12px/150% arial;}<br/></style><br/><script type="text/javascript"><br/>function a(){<br/>  var scrollTop;<br/>  var scrollLeft;<br/>  if (typeof window.pageYOffset != 'undefined') {<br/>    scrollTop = window.pageYOffset;<br/>    scrollLeft = window.pageXOffset;<br/>  }<br/>  else if (typeof document.compatMode != 'undefined' &&<br/>    document.compatMode != 'BackCompat') {<br/>    scrollTop = document.documentElement.scrollTop;<br/>    scrollLeft = document.documentElement.scrollLeft;<br/>  }<br/>  else if (typeof document.body != 'undefined') {<br/>    scrollTop = document.body.scrollTop;<br/>    scrollLeft = document.body.scrollLeft;<br/>  }<br/>  var scrollHeight = document.body.scrollHeight;<br/>  var scrollWidth = document.body.scrollWidth;<br/>  var clientWidth = document.body.clientWidth;<br/>  var clientHeight = document.body.clientHeight;<br/>  var  offsetWidth = document.body.offsetWidth;<br/>  var offsetHeight = document.body.offsetHeight;<br/>  var screenTop = window.screenTop;<br/>  var screenLeft = window.screenLeft;<br/>  var sheight = window.screen.height;<br/>  var swidth = window.screen.width;<br/>  var availHeight = window.screen.availHeight;<br/>  var availWidth = window.screen.availWidth;<br/>  <br/>  document.getElementById('scrollTop').value = scrollTop;<br/>  document.getElementById('scrollLeft').value = scrollLeft;<br/>  document.getElementById('scrollHeight').value = scrollHeight;<br/>  document.getElementById('scrollWidth').value = scrollWidth;<br/>  document.getElementById('clientWidth').value = clientWidth;<br/>  document.getElementById('clientHeight').value = clientHeight;<br/>  document.getElementById('offsetWidth').value = offsetWidth;<br/>  document.getElementById('offsetHeight').value = offsetHeight;<br/>  document.getElementById('screenTop').value = screenTop;<br/>  document.getElementById('screenLeft').value = screenLeft;<br/>  document.getElementById('sheight').value = sheight;<br/>  document.getElementById('swidth').value = swidth;<br/>  document.getElementById('availHeight').value = availHeight;<br/>  document.getElementById('availWidth').value = availWidth;<br/>}<br/></script><br/></head><br/><br/><br/><div style="width:1600px;height:1400px;margin:0 auto;font-size:12px;"><center><br/><table width="400" border="0" cellspacing="0" cellpadding="0" style="font-size:12px;margin-top:20px;"> <tr> <td width="187" align="right">scrollTop(滚动条卷过的高):</td> <td width="10">&nbsp;</td> <td width="209"><input type="text" name="scrollTop" id="scrollTop" /></td> </tr> <tr> <td align="right">scrollLeft(滚动条卷过的宽):</td> <td>&nbsp;</td> <td><input type="text" name="scrollLeft" id="scrollLeft" /></td> </tr> <tr> <td align="right">scrollHeight(内容实际高度):</td> <td>&nbsp;</td> <td><input type="text" name="scrollHeight" id="scrollHeight" /></td> </tr> <tr> <td align="right">scrollWidth(内容实际宽度):</td> <td>&nbsp;</td> <td><input type="text" name="scrollWidth" id="scrollWidth" /></td> </tr> <tr> <td align="right">clientWidth(可见区域宽):</td> <td>&nbsp;</td> <td><input type="text" name="clientWidth" id="clientWidth" /></td> </tr> <tr> <td align="right">clientHeight(可见区域高):</td> <td>&nbsp;</td> <td><input type="text" name="clientHeight" id="clientHeight" /></td> </tr> <tr> <td align="right">offsetWidth(加滚动条宽?):</td> <td>&nbsp;</td> <td><input type="text" name="offsetWidth" id="offsetWidth" /></td> </tr> <tr> <td align="right">offsetHeight(加滚动条高?):</td> <td>&nbsp;</td> <td><input type="text" name="offsetHeight" id="offsetHeight" /></td> </tr> <tr> <td align="right">screenTop:</td> <td>&nbsp;</td> <td><input type="text" name="screenTop" id="screenTop" /></td> </tr> <tr> <td align="right">screenLeft:</td> <td>&nbsp;</td> <td><input type="text" name="screenLeft" id="screenLeft" /></td> </tr> <tr> <td align="right">sheight(分辨率高):</td> <td>&nbsp;</td><br/> <td><input type="text" name="sheight" id="sheight" /></td> </tr> <tr> <td align="right">swidth(分分辨率宽):</td> <td>&nbsp;</td> <td><input type="text" name="swidth" id="swidth" /></td> </tr> <tr> <td align="right">availHeight:</td> <td>&nbsp;</td> <td><input type="text" name="availHeight" id="availHeight" /></td> </tr> <tr> <td align="right">availWidth:</td> <td>&nbsp;</td> <td><input type="text" name="availWidth" id="availWidth" /></td> </tr></table><a href="javascript:a()" style="height:20px;display:block;">内容高度是400PX,点击查看所有属性值</a><br/></center><br/></div><br/><br/>



IE6,无DTD格式声明,窗口最大化:

scrollHeight=内容的实际高度;scrollWidth=clientWidth=可视部分宽度;clientHeight=页面可视部分高度;offsetWidth=可视部分宽度+滚动条宽度+边框宽度=分辨率宽;offsetHeight=可视部分高度+4;这个4不知道是哪里的高度;

IE6,无DTD格式声明,窗口还原:

scrollHeight=内容的实际高度;scrollWidth=内容实际的宽度;clientWidth=页面可视部分宽度;clientHeight=页面可视部分高度;offsetWidth=可视部分宽度+滚动条宽度(21);offsetHeight=可视部分高度+底部滚动条高度(21);

IE6,Transitional,窗口最大化:

scrollHeight=内容的实际高度;scrollWidth=clientWidth=页面可视部分宽度; clientHeight=内容实际高度 offsetWidth=可视部分宽度offsetHeight=内容实际高度

IE6,Transitional,窗口还原:

scrollHeight=内容的实际高度;scrollWidth=内容实际的宽度; clientWidth=内容实际的宽度 clientHeight=内容的实际高度 offsetWidth=内容实际的宽度 offsetHeight=内容的实际高度;变化不是一般的大,=.=!

—————————————————分割线—————————————————-

IE7,无DTD格式声明,窗口最大化:

和IE6情况相同,那4个像素始终不知道是哪里的!

IE7,无DTD格式声明,窗口还原:

还是和IE6情况相同。

IE7,Transitional,窗口最大化:

和IE6相同,clientHeight、offsetWidth、offsetHeight的解释和无DTD时有了变化。

IE7,Transitional,窗口还原:

和IE6的不一样了,clientWidth继续保持和窗口最大化时一致=可视区域宽度;而clientHeight和offsetHeight都被解释为=内容的实际高度;offsetWidth被解释成=可视区域宽度,这点和最大化时一致,和IE6不一致;

—————————————————分割线—————————————————-

FF,无DTD格式声明,窗口最大化:

scrollHeight被解释为=可视区域的高度,和IE不同;scrollWidth=clientWidth=可视区域的宽度(页面过短,没有出现右边滚动条);clientHeight=页面可视部分高度;offsetWidth=可视部分宽度;offsetHeight=内容实际高度,和IE不同;

FF,无DTD格式声明,窗口还原:

scrollHeight=内容实际高度;scrollWidth=实际宽度+1?我很郁闷,这个1是哪里来的。clientWidth=可视区域的宽度;clientHeight=页面可视部分高度;offsetWidth=可视部分宽度;offsetHeight还是=内容实际高度;

FF,Transitional,窗口最大化:

scrollHeight=内容实际高度;scrollWidth=可视区域宽度;clientWidth=可视区域的宽度;clientHeight=内容实际高度;offsetWidth=可视部分宽度;offsetHeight还是=内容实际高度;

FF,Transitional,窗口还原:

scrollHeight=内容实际高度;scrollWidth=可视区域宽度;clientWidth=可视区域的宽度;clientHeight=内容实际高度;offsetWidth=可视部分宽度;offsetHeight还是=内容实际高度;和窗口最大化时保持一致!

—————————————————分割线—————————————————-

Opera,无DTD格式声明,窗口最大化:

scrollHeight=可视区域的高度,和火狐一样和IE不同;scrollWidth=clientWidth=可视区域的宽度(页面过短,没有出现右边滚动条);clientHeight=页面可视部分高度;offsetWidth=可视部分宽度;offsetHeight=可视部分宽度,和IE火狐都不同;

Opera,无DTD格式声明,窗口还原:

scrollHeight=内容实际高度+20,这20又是哪里的高度?;scrollWidth=内容实际宽度,与IE一致。clientWidth=可视区域的宽度;clientHeight=可视区域的高度;offsetWidth=可视部分宽度+滚动条宽度(17);offsetHeight=可视区域高度+滚动条高度(17);除scrollHeight外,其余和IE一致。

Opera,Transitional,窗口最大化:

scrollHeight=内容实际高度;scrollWidth=可视区域宽度;clientWidth=可视区域的宽度;clientHeight=内容实际高度;offsetWidth=可视部分宽度;offsetHeight还是=内容实际高度;和火狐一致

Opera,Transitional,窗口还原:

scrollHeight=内容实际高度;scrollWidth=可视区域宽度;clientWidth=可视区域的宽度;clientHeight=内容实际高度;offsetWidth=可视部分宽度;offsetHeight还是=内容实际高度;和火狐保持一致!

总结:无DTD文档格式时,各浏览器对document.body各属性的解释多种多样,在最大化和非最大化情况下解释又会有些出入,而在加上DTD文档格式后,IE7,FF,OPERA这三个浏览器表现出了惊人的一致性,只有IE6在页面内容超出窗口大小时出现了大变化(具体请看IE6部分),也就是说在正常的窗口最大化情况下,四个浏览器对这些属性的解释都是一样的,既:

scrollHeight=内容实际高度;
scrollWidth=可视区域宽度;
clientWidth=可视区域宽度;
clientHeight=内容实际高度;
offsetWidth=可视区域宽度;
offsetHeight=内容实际高度;

IE6在页面内容超出窗口大小时将宽度属性scrollWidth、clientWidth、offsetWidth都解释为内容实际宽度。

只有两种解释:所有的宽度属性(?Width)被解释为可视区域宽度,高度属性(?Height)被解释为内容实际的高度。很吃惊,但经过我多次测试(我还用高度1400、宽度为1600的内容测试过),得出的结论和上面的一致,不管是多高多宽,在申明了文档类型DTD之后,这些属性的解释就和滚动条、边框没有关系了。这个结果和网上流传的大不相同啊,哈哈!但我想我是对的!希望能传播给大家正确的知识!

建议:
1.在使用这些属性时,一定要申明文档类型!
2.IE6浏览器下要做相应的修正!
3.尽量不要用到这些属性,因为会让你很晕=.=!

, ,
Trackback

no comment untill now

Add your comment now

Please wrap all source codes with [code][/code] tags.