Javascript高级编程学习笔记(52)—— DOM2和DOM3(4)元素大小
在日常实践中,我们在使用JS的时候难免会需要获取元素的大小及位置
首先要声明的是,这一部分的内容并不属于DOM2样式规范,因为DOM中并没有对我们如何获取元素大小的相关信息做出规范
偏移量
偏移量及元素在页面中的位置
要获取元素的偏移量和下方五个属性有关:
- offsetHeight:元素的高度(包含元素的外边框及水平滚动条)
- offsetWidth:元素的宽度(包含元素的外边框及垂直滚动条)
- offsetTop:元素的上边框到包含当前元素的元素的内上边框的距离
- offsetLeft:元素的左边框到包含当前元素的元素的内左边框的距离
- offsetParent:指向包含当元素的元素
如下图所示:
所以通过以上属性,我们如果需要获取元素在页面上的偏移
则可以通过以下代码来实现:
获取水平偏移
function getElementOffsetLeft(element){ var actualLeft = element.offsetLeft; var current = element.offsetParent; while(current !=== null){ actualLeft += current.offsetLeft; current = current.offsetParent; } return actualLeft; }
获取竖直偏移
function getElementOffsetTop(element){ var actualTop = element.offsetTop; var current = element.offsetParent; while(current !=== null){ actualTop += current.offsetTop; current = current.offsetParent; } return actualTop; }
客户区大小
元素的客户区大小值得是元素内容以及其内边距所占空间的大小
也就是元素边框以内的部分(不含边框)
即元素 content 和 padding部分的大小,所以不包含滚动条部分
关于客户区域的大小有 以下两个属性可以获取相关信息:
- clientWidth:客户区域的宽度
- clinetHeight:客户区域的高度
我们可以利用上述属性来获取浏览器的视口大小,如下方代码所示:
function getViewport(){ if(document.compatMode ==="BackCompat"){ return { width: document.body.clientWidth, height: document.body.clientHeight } }else{ return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } }
滚动大小
滚动大小指的是包含滚动内容的元素大小
与元素滚动大小有关的有四个属性:
- scrollHeight:在没有滚动条的情况下,元素内容的总高度
- scrollWidth:在没有滚动条的情况下,元素内容总宽度
- scrollTop:隐藏在元素内容区域上方的像素数
- scrollLeft:隐藏在元素内容区域左侧的像素数
对于不包含滚动条的元素,scrollHeight、scrollWidth与clientHeight、clientWidth的关系并不明朗
而且以 document.documentElement 为基准,不同浏览器之间的实现存在着差异
为了保证在跨浏览器环境下取得一致的值,最好取两者中的最大值作为精确结果
如下代码所示:
var docWidth = Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth); var docHeight = Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight);
而srollTop、scrollHeight通常用于确定元素是否滚动
以及通过操作这两个属性可以让元素滚动到指定位置
确定元素大小
浏览器厂商为每个元素都提供了一个 getBoundingClientRect()方法
该方法会返回一个矩形对象,用于给出元素的大小以及相对位置
该方法的跨浏览器通用写法如下:
function getBounding(ele) {// 跨浏览器获取元素大小 var scrollTop = document.documentElement.scrollTop; var scrollLeft = document.documentElement.scrollLeft; if(ele.getBoundingClientRect){ if(typeof getBounding.offset !== "number"){ var temp = document.createElement("div"); // 修正起点坐标 temp.style.cssText = "position:absolute;left:0;top:0;"; document.body.appendChild(temp); getBounding.offset = -temp.getBoundingClientRect().top-scrollTop; document.body.removeChild(temp); temp = null; } var rect = ele.getBoundingClientRect(); var offset = getBounding.offset; return { left:rect.left + offset, right:rect.right + offset, top:rect.top + offset, bottom:rect.bottom + offset }; }else{ var actualLeft = getElementLeft(ele);// 该函数在元素偏移部分 var actualTop = getElementTop(ele);// 该函数在元素偏移部分 getElementLeft = null; getElementTop = null; return { left: actualLeft - scrollLeft, right: actualLeft + ele.offsetWidth - scrollLeft, top:actualTop - scrollTop, bottom:actualTop + ele.offsetHeight - scrollTop } } }
}