Skip to content

元素大小

元素的视窗、大小、宽高

视窗

  • viewport
  • document.documentElement.clientWidth/Height

说明 : 浏览器用户可见区域的大小

1.1 viewport

指网页的显示区域,正常情况下 viewport 跟浏览器的显示窗口是一样大小的,但是在移动设备上可能不一样大。手机浏览器的窗口为640px宽,网页的宽度为1200px,如果设置width = device-width,那么viewport的宽度就是640px 那么就会出现横向滚动条;如果我们将viewport的宽度设置成1200px,那么浏览器的显示宽度还是640px,但是显示区域宽度达到1200px,整个页面缩小了,也就不需要滚动条了。

<meta name="viewport" content="width=device-width,initial-scale=1.0, user-scalable=no">
  • width : viewport的宽度
  • height : viewport的高度
  • initial-scale : viewport的初试缩放比例
  • maximum-scale : viewport的最大缩放比例
  • minimum-scale : viewport的最小缩放比例
  • user-scalable : viewport是否允许缩放
console.log('clientWidth = ' + document.documentElement.clientWidth)    
//在Iphone 6  为 375px;   
// Chrome、FF、IE9+  为 1423px  浏览器实际宽度为 1440px  所以    document.documentElement.clientWidth  为 浏览器可视区域宽度 - 滚动条的宽度
console.log('clientHeight = ' + document.documentElement.clientHeight);

console.log('window.innerWidth = ' + window.innerWidth);
// Chrome、FF、IE9+   都是 1440px                      window.innerWidth 浏览器的可视区的宽度 包含滚动条  
// IE8-                  undefined      
console.log('window.outerWidth = ' + window.outerWidth);
// Chrome、FF、IE9+   都是 1440px                      window.outerWidth 浏览器的的宽度
// IE8-                  undefined      
console.log('clientWidth = ' + document.body.clientWidth)
// Chrome为1343px    1440- htmlmargin 15*2 - 10 - 17 
//

元素的大小

  • offsetWidth、 offsetHeight
  • clientWidth、 clientHeight
  • scrollWidht、 scrollHeight
  • width、height (css/style)
  • getBoundingClientRect()
注:
影响其计算的 box-sizing 滚动条

image

2.1 el.offsetWidth,el.offsetHeight

只读, 返回一个元素的布局大小(边框(border)、内边距(padding)、滚动条(scrollbar)(如果存在的话)、以及CSS设置的宽度高度(width)的值。)

image

2.2 el.clientWidth,el.clientHeight

只读, 返回一个元素的内部宽度 (可视宽度)(包括内边距(padding) ,但不包括垂直滚动条(如果有)、边框(border)和外边距。)

image

2.3 el.scrollWidth,el.scrollHeight

只读, 一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。 没有滚动条,其等于视口的大小(clientWidth、clientHeight),包括元素的padding,但不包括元素的border和margin,也包含 ::before 和 ::after这样的伪元素 有滚动条,内部元素的实际宽高(包含padding),但是chrome浏览器paddingBottom、paddingRight在元素内容大于元素的可用宽高时,仍然有效,但是FF、IE等会再元素的内容大于提供大小的时候会不计算paddingBottom、paddingRight

image

元素的内容其实已经略大于实际高度但是没有显示 滚动条

image

元素显示滚动条了 但是paddingTop(40px)显示了,但是paddingBottom(40px)没有作用。

image

2.2 el.getBoundingClientRect()

方法返回元素的大小及其相对于视口的位置。 此大小其实就是元素布局大小(offsetWidth,offsetHeight)

<div class="box pad10 pad10 border6" id="box1"></div>
<div class="box pad10 pad10 border6 boxBorderBox" id="box2"></div>
<br>
<div class="box pad10 pad10 border6" id="box3">
    <div style="display: inline-block;height: 300px;width: 300px;">里面的内容</div>
</div>
var box1 = document.getElementById("box1");
console.log('box1 offsetWidth = ' + box1.offsetWidth);
// chrome、ff、IE    132px    = width(100px) + 2 * padding(10px) + 2 * border(6px)     
console.log('box1 offsetHeight = ' + box1.offsetHeight);
// chrome、ff、IE    132px    = width(100px) + 2 * padding(10px) + 2 * border(6px)  
console.log('box1 clientWidth = ' + box1.clientWidth);
// chrome、ff、IE    120px    = width(100px) + 2 * padding(10px)
console.log('box1 clientHeight = ' + box1.clientHeight);
// chrome、ff、IE    120px    = width(100px) + 2 * padding(10px)
console.log('box1 scrollWidth = ' + box1.scrollWidth);
// chrome、ff、IE7+   120px    = width(100px) + 2 * padding(10px)
// IE7                20px    =  2 * padding(10px)
console.log('box1 scrollHeight = ' + box1.scrollHeight);
// chrome、ff、IE7+    120px    = width(100px) + 2 * padding(10px)
// IE7                20px    =  2 * padding(10px)
console.log('box1 getBoundingClientRect = ' + objectToString(box1.getBoundingClientRect()))
// chrome、ff、IE    {  height = 132, width = 132 }
console.log('box1 css width = ' + getStyle(box1,'width'))
// chrome、ff、IE7+    100px    
console.log('box1 css height = ' + getStyle(box1,'height'))
// chrome、ff、IE7+    100px    

var box2 = document.getElementById("box2");
console.log('box2 offsetWidth = ' + box2.offsetWidth);
// chrome、ff、IE    100px    = 元素内可视区大小width(68px) + 2 * padding(10px) + 2 * border(6px)     
console.log('box2 offsetHeight = ' + box2.offsetHeight);
// chrome、ff、IE    100px    = 元素内可视区大小height(68px) + 2 * padding(10px) + 2 * border(6px)  
console.log('box2 clientWidth = ' + box2.clientWidth);
// chrome、ff、IE    88px    = 元素内可视区大小width(68px) + 2 * padding(10px)
console.log('box2 clientHeight = ' + box2.clientHeight);
// chrome、ff、IE    88px    = 元素内可视区大小height(68px) + 2 * padding(10px)
console.log('box2 scrollWidth = ' + box2.scrollWidth);
// chrome、ff、IE7+   88px    = 元素内可视区大小width(68px) + 2 * padding(10px)
// IE7                20px    =  2 * padding(10px)
console.log('box2 scrollHeight = ' + box2.scrollHeight);
// chrome、ff、IE7+    88px    = 元素内可视区大小height(68px) + 2 * padding(10px)
// IE7                20px    =  2 * padding(10px)
console.log('box2 getBoundingClientRect = ' + objectToString(box2.getBoundingClientRect()))
// chrome、ff、IE    {  height = 100, width = 100 }
console.log('box2 css width = ' + getStyle(box2,'width'))
// chrome、ff、IE7+    100px 
console.log('box2 css height = ' + getStyle(box2,'height'))
// chrome、ff、IE7+    100px    

var box3 = document.getElementById("box3");
console.log('box3 offsetWidth = ' + box3.offsetWidth);
// chrome、ff、IE    132px    = 元素内可视区大小width(100px) + 2 * padding(10px) + 2 * border(6px)     
console.log('box3 offsetHeight = ' + box3.offsetHeight);
// chrome、ff、IE    132px    = 元素内可视区大小height(100px) + 2 * padding(10px) + 2 * border(6px)  
console.log('box3 clientWidth = ' + box3.clientWidth);
// chrome、ff、IE    103px    = 元素内可视区大小width(100px) + 2 * padding(10px) - 滚动条宽度(17px);
console.log('box3 clientHeight = ' + box3.clientHeight);
// chrome、ff、IE    103px    = 元素内可视区大小height(100px) + 2 * padding(10px) - 滚动条宽度(17px);
console.log('box3 scrollWidth = ' + box3.scrollWidth);
// chrome            320px    = 元素子元素内容的宽度(300px) + 2 * padding(10px)
// FF,IE7+           310px    = 元素子元素内容的宽度(300px) + paddingLeft(10px)
console.log('box3 scrollHeight = ' + box3.scrollHeight);
// chrome            320px    = 元素子元素内容的高度(300px) + 2 * padding(10px)
// FF,IE7+           310px    = 元素子元素内容的高度(300px) + paddingTop(10px)
console.log('box3 getBoundingClientRect = ' + objectToString(box3.getBoundingClientRect()))
// chrome、ff、IE    {  height = 132, width = 132 }
console.log('box3 css width = ' + getStyle(box3,'width'))
// chrome、ff、IE7+    100px 
console.log('box3 css height = ' + getStyle(box3,'height'))
// chrome、ff、IE7+    100px

元素的位置

  • offsetParent、offsetTop、offsetLeft
  • clientTop、clientLeft
  • scrollTop、clientLeft
  • getBoundingClientRect().top、left

3.1 offsetParent、offsetTop、offsetLeft

offsetParent 是一个只读属性,返回一个指向最近的(closest,指包含层级上的最近)包含该元素的定位元素。如果没有定位的元素,则 offsetParent 为最近的 table, table cell 或根元素(标准模式下为 html;quirks 模式下为 body)。当元素的 style.display 设置为 "none" 时,offsetParent 返回 null。offsetParent 很有用,因为 offsetTop 和 offsetLeft 都是相对于其内边距边界的。

  • 如果没有定位父级 Chrome、firefox、ie8+ 都是BODY IE7- 如果元素本身存在定位属性则是 HTML 如果元素本身没有定位属性就是 BODY
  • 如果有定位父级
    如果中间存在有layout的父级
    Chrome、firefox、ie8+ 定位父级 IE7- layout父级
  • 如果元素本身 有display : none; 其offsetLeft/offsetTop 都为 0
  • 如果元素本身 position : fixed; 其offsetParent 为null , offsetLeft/offsetTop 都为相对于HTML的定位
document.getElementById("offsetParent4").style.display = 'none';
console.log(document.getElementById("offsetParent4").offsetParent);
console.log(document.getElementById("offsetParent4").offsetLeft);
console.log(document.getElementById("offsetParent4").offsetTop);
//在Chrome 下为  null   0     0 
//在firefox下为  null   0     0 
// 在IE 11+      null   0     0 
// 在IE 10-      body
document.getElementById("offsetParent5").style.position = 'fixed';
console.log(document.getElementById("offsetParent5").offsetParent);
console.log(document.getElementById("offsetParent5").offsetLeft);
console.log(document.getElementById("offsetParent5").offsetTop);
//在Chrome 下为  null   8px    29px
//在firefox下为  null   8px    30px
// 在IE 8+      null   8px    26px
// 在IE 7-      null   跟多
document.getElementById("offsetParent5").style.position = 'absolute';
console.log(document.getElementById("offsetParent5").offsetParent);
console.log(document.getElementById("offsetParent5").offsetLeft);
console.log(document.getElementById("offsetParent5").offsetTop);
//在Chrome 下为  body   8px    29px
//在firefox下为  body   8px    30px
// 在IE 8+      body   8px    26px
// 在IE 7-      HTML    跟多

// IE7及以下怪异问题:  如果元素本身没有设置定位属性  则offsetParent为body,如果设置了定位属性 则offsetParent为html。

document.getElementById("offsetParent3").style.position = 'relative';
console.log(document.getElementById("offsetParent3").offsetParent.tagName);    //HTML
document.getElementById("offsetParent3").style.position = 'static';
console.log(document.getElementById("offsetParent3").offsetParent.tagName);    //BODY

//在IE8+及其他  都是  body
//在IE7-    显示的确实offsetParent2   原因就是  layout

document.getElementById("offsetParent2").style.zoom = 1;
console.log(document.getElementById("offsetParent3").offsetParent.id);    //offsetParent2

// offsetLeft/offsetTop
// 作用:  元素的左外边框至定位父级的左内边框之间的像素距离,其跟offsetParent息息相关

// 如果html/body的 
document.documentElement.style.padding = '10px 20px';
document.documentElement.style.margin = '0';
document.body.style.padding = '15px 25px';
document.body.style.margin = '0';

console.log(document.getElementById('offsetParent3').offsetParent.tagName);  // 25px
console.log(document.getElementById('offsetParent3').offsetTop);  // 25px
console.log(document.getElementById('offsetParent3').offsetLeft); // 45px
//在Chrome 下为  BODY   26px 46px     //  HTML(10px) + body(15px);
//在firefox下为  BODY   25px 45px     //  HTML(10px) + body(15px);
// 在IE 7+       BODY   25PX 45PX     //  HTML(10px) + body(15px);
// 在IE 7-       HTML   25PX 45PX     //  HTML(10px) + body(15px);

// 默认定位的都是HTML

3.2 clientTop、el.clientLeft

只读, 一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距

image

var client1 = document.getElementById('client1');

client1.style.cssText = ';overflow-y:auto;display:inline-block;height: 40px;width: 500px;word-wrap: break-word;' + ';margin: 50px;border: 20px solid red; padding: 30px;';

console.log(client1.clientTop);   // 20px  正好为border的宽度
console.log(client1.clientLeft);  // 20px  正好为border的宽度
//在Chrome 下为  20px 20px
//在firefox下为  20px 20px
// 在IE 7+       20px 20px
// 在IE 7-       20px 20px

//设置滚动条在 左侧
client1.style.direction = 'rtl';
console.log(client1.clientTop);   // 20px  正好为border的宽度
console.log(client1.clientLeft);  // 37px  正好为border的宽度 + 滚动条的宽度
//在Chrome 下为  20px 37px
//在firefox下为  20px 37px
// 在IE 7+       20px 20px     // 正鸡儿怪异  不算滚动条了
// 在IE 7        20px 37px

3.3 el.scrollLeft,el.scrollTop

可读可写,可以获取或设置一个元素的内容垂直滚动的像素数

image

获取元素是否滚动到底部
console.log(client1.scrollHeight - client1.clientHeight === client1.scrollTop);

滚动条

元素的内容超过可视区的时候就会出现滚动条。且滚动条占用padding的宽度

重点:
1、滚动条占用padding的区域,当padding的宽度小于滚动条的宽度的时候 clientWidth = width + paddingLeft + paddingRight - 滚动条