在web开发中,不可避免遇到要计算元素大小以及位置的问题,解决这类问题的方法是利用DOM提供的一些API结合兼容性处理来,所有内容大概分3篇左右的文章的来说明。本文作为第一篇,介绍DOM提供的与尺寸大小相关的DOM属性,提供一些兼容性处理的方法,并结合常见的场景说明如何正确运用这些属性。
1. 正确理解offsetWidth、clientWidth、scrollWidth及相应的height属性
假设某一个元素的横纵向滚动条都拖动到最末端,则offsetWidth、clientWidth、scrollWidth等属性相应的范围如下图所示:
1)offsetWidth ,offsetHeight对应的是盒模型的宽度和高度,这两个值跟我们使用chrome审查元素时看到的尺寸一致:
2)scrollWidth,与scrollHeight对应的是滚动区域的宽度和高度,但是不包含滚动条的宽度!滚动区域由padding和content组成。
3)clientWidth,clientHeight对应的是盒模型除去边框后的那部分区域的宽度和高度,不包含滚动条的宽度。
4)任何一个DOM元素,都可以通过以下api快速得到offsetWidth,clientWidth,scrollWidh及相关的height属性:
1 2 3 4 5 6 7 |
//domE为一个DOM Html Element对象 domE.scrollWidth domE.scrollHeight domE.clientWidth domE.clientHeight domE.offsetWidth domE.offsetHeight |
5)这些属性在现代浏览器包括pc和mobile上几乎没有兼容性问题,可以放心使用。如果你想了解详细的兼容性规则,可以参考下面的2篇文章:
W3C DOM Compatibility – CSS Object Model View
cssom视图模式cssom-view-module相关整理与介绍
下面针对普通html元素,html根元素和body元素的以上相关属性一一测试,以便验证前面的结论,总结一些可在实际编码过程中直接使用的经验技巧。之所以要区分普通html元素,html根元素和body元素,是因为前面的理论,在html根元素和body元素会有一些怪异之处,需要小心处理。
注:
1、为了减少篇幅,测试贴出的代码不是完整的代码,但不影响学习参考,另外文中给出的测试结果都是在chrome(版本:45.0)下运行得出的,在测试结果有差异的情况下,还会给出IE9,IE10,IE11,firefox(版本:42.0),opera(版本:34.0)的测试结果,没有差异的会在测试结果中说明,不考虑IE8及以下。
2、safari因为设备限制暂不测试,另外它跟chrome内核相同,对标准支持的可靠性差不到哪去。
3、老版本的chrome,firefox,opera也因为设备的限制无法测试,不过从浏览器对标准的支持程度考虑,这三个浏览器在很早的版本开始对W3C的标准都是比较规矩的,加之这些浏览器更新换代的速度较快,现在市面上这些浏览器主流的版本也都是较新的。
4、由于不考虑IE8及以下,同时html现在都用html5,所以document.compatMode = ‘BackCompat’ 的情况不考虑。不过尽管BackCompat模式是IE6类的浏览器引出的,但是对于chrome,firefox等也存在document.compatMode = ‘BackCompat’ 的情况,比如下面的这个网页,你用chrome打开,并且在console中打印document.compatMode,你会发现它的值也是BackCompat(原因跟该页面用的是html4.0的dtd有关,如果换成html4.01的dtd就不会在chrome和firefox里出现该情况了):
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/compatModeCompat.htm
更多关于compatMode的知识,你可以通过下面的几个资源学习:
https://developer.mozilla.org/zh-CN/docs/Web/API/Document/compatMode
https://msdn.microsoft.com/en-us/library/ms533687(VS.85).aspx
http://www.cnblogs.com/uedt/archive/2010/09/21/1832402.html
测试一、验证普通html元素(非body及html根元素)的offsetWidth、clientWidth、scrollWidth及相关height属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<style type="text/css"> html, body { margin: 0; } body { padding: 100px; } .box { overflow: scroll; width: 400px; height: 300px; padding: 20px; border: 10px solid #000; margin: 0 auto; box-sizing: content-box; } .box-2 { border: 1px solid #000; } </style> <body> <div class="box"> <div class="box-2">...</div> </div> </body> <script type="text/javascript"> var boxE = document.querySelectorAll('.box')[0]; console.log('scrollWidth:' + boxE.scrollWidth); console.log('scrollHeight:' + boxE.scrollHeight); console.log('clientWidth:' + boxE.clientWidth); console.log('clientHeight:' + boxE.clientHeight); console.log('offsetWidth :' + boxE.offsetWidth); console.log('offsetHeight:' + boxE.offsetHeight); </script> |
在这个例子中,box元素有400*300的宽高,20px的padding和10px的border,chrome下对应的盒模型:
js执行结果:
从盒模型与js执行结果可知:
1)offsetWidth与offsetHeight与chrome审查元素看到的尺寸完全一致;
2)clientWidth与clientHeight分别等于offsetWidth与offsetHeight减掉相应边框(上下共20px,左右共20px)和滚动条宽度后的值(chrome下滚动条宽度为17px);
3)对于scrollWidth由于没有发生横向的溢出,同时由于overflow: scroll的原因,scrollWidth 跟clientWidth相同,但是没有包含滚动条的宽度,这也验证了前面提出的结论;
4)对于scrollHeight,在这个例子中,它其实等于上下padding(共40px) + div.box-2的offsetHeight(1370px),div.box-2:
5)以上测试还有一个css值得注意,就是box-sizing,以上代码中box-sizing设置为了content-box,如果把它改成border-box,结果也是类似的,因为offsetWidth,clientWidth还有scrollWidth对应的区域不会发生改变。
6)其它浏览器运行结果与1-5的结论一致。
测试二、验证html根元素和body元素的相关offset client scroll宽高属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ۓ合常见的场景说明如何正确运用这些属性。
1. 正确理解offsetWidth、clientWidth、scrollWidth及相应的height属性假设某一个元素的横纵向滚动条都拖动到最末端,则offsetWidth、clientWidth、scrollWidth等属性相应的范围如下图所示: 1)offsetWidth ,offsetHeight对应的是盒模型的宽度和高度,这两个值跟我们使用chrome审查元素时看到的尺寸一致: 2)scrollWidth,与scrollHeight对应的是滚动区域的宽度和高度,但是不包含滚动条的宽度!滚动区域由padding和content组成。 3)clientWidth,clientHeight对应的是盒模型除去边框后的那部分区域的宽度和高度,不包含滚动条的宽度。 4)任何一个DOM元素,都可以通过以下api快速得到offsetWidth,clientWidth,scrollWidh及相关的height属性:
5)这些属性在现代浏览器包括pc和mobile上几乎没有兼容性问题,可以放心使用。如果你想了解详细的兼容性规则,可以参考下面的2篇文章: W3C DOM Compatibility – CSS Object Model View cssom视图模式cssom-view-module相关整理与介绍 下面针对普通html元素,html根元素和body元素的以上相关属性一一测试,以便验证前面的结论,总结一些可在实际编码过程中直接使用的经验技巧。之所以要区分普通html元素,html根元素和body元素,是因为前面的理论,在html根元素和body元素会有一些怪异之处,需要小心处理。 注: 1、为了减少篇幅,测试贴出的代码不是完整的代码,但不影响学习参考,另外文中给出的测试结果都是在chrome(版本:45.0)下运行得出的,在测试结果有差异的情况下,还会给出IE9,IE10,IE11,firefox(版本:42.0),opera(版本:34.0)的测试结果,没有差异的会在测试结果中说明,不考虑IE8及以下。 2、safari因为设备限制暂不测试,另外它跟chrome内核相同,对标准支持的可靠性差不到哪去。 3、老版本的chrome,firefox,opera也因为设备的限制无法测试,不过从浏览器对标准的支持程度考虑,这三个浏览器在很早的版本开始对W3C的标准都是比较规矩的,加之这些浏览器更新换代的速度较快,现在市面上这些浏览器主流的版本也都是较新的。 4、由于不考虑IE8及以下,同时html现在都用html5,所以document.compatMode = ‘BackCompat’ 的情况不考虑。不过尽管BackCompat模式是IE6类的浏览器引出的,但是对于chrome,firefox等也存在document.compatMode = ‘BackCompat’ 的情况,比如下面的这个网页,你用chrome打开,并且在console中打印document.compatMode,你会发现它的值也是BackCompat(原因跟该页面用的是html4.0的dtd有关,如果换成html4.01的dtd就不会在chrome和firefox里出现该情况了): 更多关于compatMode的知识,你可以通过下面的几个资源学习: https://developer.mozilla.org/zh-CN/docs/Web/API/Document/compatMode https://msdn.microsoft.com/en-us/library/ms533687(VS.85).aspx http://www.cnblogs.com/uedt/archive/2010/09/21/1832402.html
测试一、验证普通html元素(非body及html根元素)的offsetWidth、clientWidth、scrollWidth及相关height属性:
在这个例子中,box元素有400*300的宽高,20px的padding和10px的border,chrome下对应的盒模型: js执行结果: 从盒模型与js执行结果可知: 1)offsetWidth与offsetHeight与chrome审查元素看到的尺寸完全一致; 2)clientWidth与clientHeight分别等于offsetWidth与offsetHeight减掉相应边框(上下共20px,左右共20px)和滚动条宽度后的值(chrome下滚动条宽度为17px); 3)对于scrollWidth由于没有发生横向的溢出,同时由于overflow: scroll的原因,scrollWidth 跟clientWidth相同,但是没有包含滚动条的宽度,这也验证了前面提出的结论; 4)对于scrollHeight,在这个例子中,它其实等于上下padding(共40px) + div.box-2的offsetHeight(1370px),div.box-2: 5)以上测试还有一个css值得注意,就是box-sizing,以上代码中box-sizing设置为了content-box,如果把它改成border-box,结果也是类似的,因为offsetWidth,clientWidth还有scrollWidth对应的区域不会发生改变。 6)其它浏览器运行结果与1-5的结论一致。
测试二、验证html根元素和body元素的相关offset client scroll宽高属性:
|