DOM之度量

一个网页就是一个图纸,前端工程师的任务就是把图纸中所有元素的尺寸和大小规划好,然后把它们安放在图纸相应的位置。有时候我们需要度量元素的位置和坐标,那么我们来复习一下和度量有关的那些事儿吧~翻译原文的链接here


css盒模型


一个文档例子

<div id="example">
  
## Introduction   

  The contents. 
</div>

这个文档盒子绝对定位,有borders、paddings、margins、和滚动条:

#example {
  position: absolute;

  width: 300px;
  height: 200px;

  left: 160px;
  top: 160px;

  padding: 20px;
  margin: 20px;

  overflow: auto;
  border: 25px solid #F0E68C;
}

然后我们看看css样式对这个盒子起的作用,看上面的数字标注,很清晰吧。


盒子的度量

css中的width和height:指的是内容区域的大小,即padding之内的区域。css的属性可以用element.style来设置,并用getComputedStyle()/currentStyle来读取。

那么在js的世界里是如何得到各种width和height呢?所有的js度量都是以px为单位的,但是省略了px这个符号

clientWidth/clientHeight: 带padding不带滚动条的的内容区域

计算如下:

clientWidth = 300(width) + 40(paddings) - 16(scrollbar) = 324
clientHeight = 200(height) + 40(paddings) = 240

如果没有padding,clientWidth/clientHeight展示的就是实际的内容区域大小了:

从上图可以看出,css的width包括了滚动条,你不能插入一个300px的元素到这个盒子里,真正可用的区域宽度是clientWidth.

scrollWidth/scrollHeight:

scrollWidth/scrollHeight和clientWidth/clientHeight一样,但是包含了整个可以滚动的区域。例如可以用下面的代码使得垂直方向上展示出所有内容:

element.style.height = element.scrollHeight + 'px';

scrollTop/scrollLeft:溢出部分的距离

scrollLeft/scrollTop是可写的。

offsetWidth/offsetHeight: 包含border不包含margin的长度。

clientTop/clientLeft: top/left的border的长度。

offsetParent/offsetLeft/offsetTop: offsetLeft和offsetTop反映了元素相对于它的offsetParent的偏移量。offsetParent是在布局上的父元素,例如:如果一个元素是绝对定位,那么offsetParent不是它的DOM上的父元素,而是离它最近的被定位过的元素(postion为非static的元素,如果没有则是body或者table cell)。

注意:js中的坐标系统和大小值都只会设置给可见的元素。如果元素是display:none的话,所有值为0,并且它的offsetParent为null。

我们可以利用这一特性来判断一个元素是否可见:

function isHidden(elem)
  return !elem.offsetWidth && !elem.offsetHeight
}
//即使父元素为display:none也适用
//有些浏览器不能识别TR
//不能适用:visibility:hidden的或者被定为移出了可视区域的情况

突然想起一道面试题,怎么判断一个元素是否可见?咿呀。。。。不是简单的一种情况呀,有兴趣的可以想想哦~

附上整体一个图:

貌似这张图更清晰,再附上: