Appearance
元素大小
元素的视窗、大小、宽高
视窗
- 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 滚动条
2.1 el.offsetWidth,el.offsetHeight
只读, 返回一个元素的布局大小(边框(border)、内边距(padding)、滚动条(scrollbar)(如果存在的话)、以及CSS设置的宽度高度(width)的值。)
2.2 el.clientWidth,el.clientHeight
只读, 返回一个元素的内部宽度 (可视宽度)(包括内边距(padding) ,但不包括垂直滚动条(如果有)、边框(border)和外边距。)
2.3 el.scrollWidth,el.scrollHeight
只读, 一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。 没有滚动条,其等于视口的大小(clientWidth、clientHeight),包括元素的padding,但不包括元素的border和margin,也包含 ::before 和 ::after这样的伪元素 有滚动条,内部元素的实际宽高(包含padding),但是chrome浏览器paddingBottom、paddingRight在元素内容大于元素的可用宽高时,仍然有效,但是FF、IE等会再元素的内容大于提供大小的时候会不计算paddingBottom、paddingRight
元素的内容其实已经略大于实际高度但是没有显示 滚动条
元素显示滚动条了 但是paddingTop(40px)显示了,但是paddingBottom(40px)没有作用。
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
只读, 一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距
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
可读可写,可以获取或设置一个元素的内容垂直滚动的像素数
获取元素是否滚动到底部
console.log(client1.scrollHeight - client1.clientHeight === client1.scrollTop);
滚动条
元素的内容超过可视区的时候就会出现滚动条。且滚动条占用padding的宽度