1)body元素由于10px边框的原因,所以clientWidth比offsetWidth少了20px,这跟前面提到的理论是一致的,但是不可思议的是body的scrollWidth/scrollHeight竟然等于它的offsetWidth/offsetHeight,scrollWidth/scrollHeight是元素滚动区域的宽高度,按照前面给出的范围图来理解,body的scrollWidth/scrollHeight应该小于它的offsetWidth/offsetHeight才对;
2)docE的scrollWidth跟scrollHeight,应该等于body元素的offsetWidth跟offsetHeight,从运行结果来看,这一点是符合的,但是docE的clientWidth竟然等于它的offsetWidth,按照范围图,docE的clientWidth应该等于offsetWidth减去滚动条宽度才对。
其它的浏览器运行结果与chrome也有较大的差异:
IE11:
1)IE11下body元素没有出现chrome下body元素的问题
2)IE11下html根元素也有chrome类似的问题
IE10,IE9:
1)IE10,9下body元素没有出现chrome下body元素的问题
2)IE10,9下html根元素也没有chrome类似的问题
firefox:与IE11运行结果一致。
opera: 与chrome运行结果一致,可能是因为我这个版本的opera用的跟chrome一样的webkit内核的原因。
看起来IE9就跟IE10是最正常的,实在是有点难以理解,网上搜索很久,也没有找到相关资料来说明这些差异, 最后也只能采取大胆假设的方式,猜测出几个能解释这些问题的原因 :
1) 首先,网页整体的滚动,跟普通html元素的滚动不一样,普通html元素自身就是滚动对象, 但是对于网页来说,滚动对象不一定是html根元素或者body元素。因为当body内容为空时,body的高度是0,html根元素的高度也是0,如果这个时候给html或body加上overflow: scroll的css,会看到滚动条还是出现浏览器窗口的右边跟底边,所以对于网页整体的滚动,理论上,滚动对象应该是window,而不是html元素或者body元素!但实际情况并非如此,就测试的浏览器而言:
对于IE10,IE9,它的滚动对象是html根元素,所以它们的html根元素的offset会包含滚动条的宽度;
对于其它浏览器,滚动对象是window,所以它们的html根元素的offset不包含滚动条的宽度。
2)第二,普通元素发生滚动时,滚动内容=它的content区域+它的padding区域,当网页整体滚动时,滚动内容应该是html根元素!但实际情况也并非如此,就测试的浏览器而言:
对于IE9,IE10,IE11,firefox,它们的滚动区域是html根元素,所以它们的documentElement的scrollWidth和scrollHeight始终表示网页整体的滚动区域大小!
对于chrome和opera,它们的滚动对象是body元素,所以它们的body的scrollWidth和scrollHeight始终表示网页整体的滚动区域大小!
3)第三,浏览器始终把documentElement.clientWidth和documentElement.clientHeight描述为网页可视区域除去滚动条部分的大小,跟网页内容没有关系!
以上的这些推断也并非是毫无道理,就拿滚动对象和滚动区域来说:chrome下如果要用js滚动页面到某个位置,在不使用window.scrollTo的条件下,就必须用document.body.scrollTop = xxx 来处理,而设置document.documentElement.scrollTop无效,说明chrome的整体滚动区域是由body的滚动区域决定的;而IE11和火狐下如果要用js滚动页面到某个位置,在不使用window.scrollTo的条件下,就必须用document.documentElement.scrollTop = xxx来处理,设置document.body.scrollTop无效,说明IE11和火狐的整体滚动区域是由html根元素的滚动区域决定的。
2. 利用JS准确获取DOM对象的大小
常见的场景有:
1)获取整个网页的可视区域的大小,不包括滚动条
2)获取整个网页的大小,包括不可见的滚动区域
3)获取一个普通html元素的大小
4)判断元素或网页有无出现滚动条
5)计算滚动条的宽度