JavaScript client、offset、scroll 属性获取元素大小及偏移
1.元素偏移量属性:每次访问需要重新计算
A.offsetHeight和offsetWidth可以得到元素的宽度和高度
offetHeight(offsetWidth) = padding + height(width) + border;
B.offsetLeft和offsetTop:
a.offsetParent该元素计算offsetLeft(offsetTop)值所选的参考对象和parentNode不等价
b.该元素有定位则参考的对象为最近的带有定位最近带有定位的父元素没有定位则参考他的父
元素,所以offsetParent有可能不是直接包含他的父元素
c.值是从参考元素边框内侧开始不包含border包含padding,
d.使用offsetLeft(offsetTop)结合offsetParent来计算元素在页面的偏移量,比如计算元素
相对页面的左偏移量
/*以下的函数在《JavaScript高级程序设计第三版》321页*/
```
function getELementLeft(element) {
var actualLeft = element.offsetLeft;
var offsetParent = element.offsetParent;
while(offsetParent !== null) {
actualLeft += current.offsetLeft;
offsetParent = offsetParent.offsetParent;
}
return actualLeft;
}
```
D.offsetLeft(offsetTop)与style.left(style.top)区别,结合以下代码分析:
a.如果盒子没有定位style.left获取不到值输出空,而offsetLeft则输出盒子离body左内边框
的距离
b.offet.Width返回值默认以像素为单位的数值不带px,style.width返回字符窜带px
c.style.left只能取到行内的left属性值,如果没有指定只会返回空字符串,offsetLeft获
取则没有这个限制
d.style.left可以读写,offsetLeft只读
/代码片一/
div {
margin: 0;
padding: 0;
left: 10px;
width: 100px;
height: 100px;
border: solid 1px red;
}
.hasPosition {
position: absolute;
overflow: scroll;
}
<div class="hasPosition" style="left: 20px; ">
是的哈是个大家爱好是大家爱帅哥的骄傲是更好的骄傲啥感觉多少噶绝对是噶价格多少家阿哥大家哈就打击和大家按实际萨嘎撒谎个等级撒大家爱喝酒打架后多久啊回到家阿嘎时间过得
</div>
<div class="noPosition" style=" ">
是的哈是个大家爱好是大家爱帅哥的骄傲是更好的骄傲啥感觉多少噶绝对是噶价格多少家阿哥大家哈就打击和大家按实际萨嘎撒谎个等级撒大家爱喝酒打架后多久啊回到家阿嘎时间过得
</div>
<script>
var hasPosition = document.querySelector('.hasPosition');
console.log(hasPosition.offsetLeft); // 20
console.log(hasPosition.style.left); // 20px
var noPosition = document.querySelector('.noPosition');
console.log(noPosition.offsetLeft); // 8
console.log(noPosition.style.left); // "" 空
/*3.元素内容滚动大小*/
console.log(noPosition.scrollHeight); // 308
console.log(hasPosition.scrollHeight); // 374
</script>
2.客户区大小:值指的是元素内容及其内边距所占据的空间大小,不包括滚动条
A.clientWidth(clientHeight) = padding + width(height);
B.可以用来获取视口的大小:
/* 以下的函数是对《JavaScript高级程序设计第三版》323页函数的修改得到获取视口的兼容性函数*/
function getViewport() {
/*W3C浏览器*/
if(window.innerWidth) {
return {
width: window.innerWidth;
height: window.innerHeight;
}
}else if(document.compatMode == 'BackCompat') {
/*文档模式为标准模式*/
return {
width: document.documentElement.clientWidth;
height: document.documentELement.clientHeight;
}
}else {
/*文档模式为混杂模式*/
return {
width: document.body.clientWidth;
height: document.body.clientHeight;
}
}
}
3.元素内容滚动大小结合上面代码片一
A.scrollWidth(scrollHeight):
a.没有滚动条:值为元素内容的宽度(高度)
b.存在滚动条:值?暂时不知道怎么算,在谷歌上面测试了看不出值的规律
c.html元素被当成是在web浏览器视口中滚动元素,因此带垂直滚动条并不带横向滚动条的页
面高度为:
(1).标准模式:document.documentElement.scrollHeight;
(2).混杂模式:document.body.scrollHeight
d.不带滚动条的页面大小clientWidth(clientWidth)和scrollWidth(scrollHeight)关系在不
同浏览器中是不同的(标准模式)IE混合模式只需将以下的documentElemnt换成body:
(1).这里和视口的联系在于没有滚动条说明内容区域有可能的最大值为视口大小,有滚动条
页面的内容大小就超出视口的大小,两者就没有明确联系
(2).Firefox 中documentElement两组属性始终都是相等的,大小代表的是文档内容区域的大
小,而不是视口的大小
(3).Opera,Safari3.1,及更高版本、Chrome中的scrollWidth(scrollHeight)等于视口的大小
,clientWidth(clientHeight)等于文档内容区域的大小
(4).IE(在标准模式)中scrollWidth(scollHeight)等于文档区域的大小,
clientWidth(clientWidth)等于视口的大小
B.scrollLeft(scrollTop):被隐藏在可视内容区域左边(上边)的像素数,通过设置该属性值可以
改变元素的的滚动位置,比如以下函数就是设重置元素的滚动状态回到最初的状态
function resetScrollTop(element) {
if(element.scrollTop != 0) {
element.scrollTop = 0;
}
}
4.确定元素的大小
A.思路:获得元素在相对视口的left,top,right,bottom,视口的元素坐标又是和页面原始坐标相同,通过left(top)和right(bottom)的差值来计算元素的宽高,包含边框
a.W3C:页面的原始坐标是(0,0)即视口的原始坐标为(0,0)W3C提供了一个getBoundingC
lientRect()函数来获取以上属性值
b.IE8以下:页面的原始坐标(2,2)即视口的原始坐标为(2,2),所以需要自己封装函数来
获取元素属性,IE8使用以上**元素偏移属性中的函数**getElementLeft()函数和
getElementTop()以上没有封装getElementLeft()一样用来取得元素相对页面的top或left值
c.right和bottom参考文档在左上角的原始坐标的话,就和CSS中的right,bottom不相同,也即
是right值是从页面的最左端算起,不是在最有端来算得
/《JavaScript高级程序设计第三版》325页的函数/
function getBoundingClientRect(element) {
var scrollTop = document.documentELement.scrollTop;
var scrollLeft = document.documentELement.scrollLeft;
if(element.getBoundingClientRect) {
/*
a.将left,right,top,bottom属性组成的对象放到函数的offset属性中,
b.以下代码是实现懒加载,因为在某个浏览器里面我们只需要初始化一次offset值就可以
c.offset是用来准确获取元素在W3C浏览器中页面滚动相对视口的位置
*/
if(typeof arguments.callee.offset != 'number') {
/*以下是通过创建一个div实例来矫正再通过四个属性中的top属性来矫正*/
var tem = document.creatElement('div');
document.body.appendChild(temp);
/*
a.减去页面scrolltop是因为页面可能是被滚动了,
b.避免页面滚动后得重新调用该函数
*/
arguments.callee.offset = -temp.getBoundingClientRect().top - scrolltop;
temp = null;
}
var sect = element.getBoundingClientRect();
var offset = arguments.callee.offset;
return {
left: rect.left + offset;
right: rect.right + offset;
top: rect.top + offset;
bottom: rect.bottom + offset;
};
}else {
/*以上元素偏移属性中的函数*/
var actualLeft = getElementLeft(element);
var actualTop = getElementTop(element);
return {
left: actualLeft - srollLeft;
right: actualLeft + element.offsetWidth - srollLeft;
top: actualTop - srollTop;
bottom: actualTop + element.offsetHeight - srollTop;
}
}
}
参考书籍:《JavaScript高级程序设计第三版》