DOM中的元素位置和大小的计算方法,含jquery和dojo方法
原生维度属性
DOM中设计到位置和大小的几个作用在Element上的属性有下面一个列表。按照DOM标准,它们应该如下。但不同的浏览器会存在差异。
属性名 | 作用域 | 读写 | 描述 |
offsetTop | DOM node | 只读 | 元素上外边框距离包含它的定位元素(offsetParent)或根节点的上内边框距离。 |
offsetLeft |
DOM node | 只读 | 元素左外边框距离包含它的定位元素(offsetParent)或根节点的左内边框距离。 |
offsetWidth | DOM node | 只读 | 元素的左右边框宽度+左右内边距+内容区width |
offsetHeight | DOM node | 只读 | 元素的上下边框宽度+上下内边距+内容区height |
offsetParent | DOM node | 只读 | 包含元素的最近的已经定位元素,如果没有则为null. |
clientTop | DOM node | 只读 | 元素上边框宽度 |
clientLeft | DOM node | 只读 | 元素左边框宽度 |
clientWidth | DOM node | 只读 | 左右内边距+内容区width |
clientHeight | DOM node | 只读 | 上下内边距+内容区height |
scrollTop | DOM node | 读写 | 内容区隐藏在可见区域以外,距离最高内边框的长度。可通过写来改变滚动条位置。(body例外) |
scrollLeft | DOM node | 读写 | 内容区隐藏在可见区域以外,距离最左边内边框的距离。(body例外) |
scrollWidth | DOM node | 只读 | 滚动区域的内容的宽度,可能会超过clientWidth |
scrollHeight | DOM node | 只读 | 滚动区域的内容的高度,可能会超过clientHeight |
innerWidth | window | 只读 | 浏览器视窗的宽度 |
innerHeight | window | 只读 | 浏览器视窗的高度 |
根据上面的表格,如果想计算一个element上外边框距离document最顶端的距离,应该用下面的计算方法:
var distance=e.offsetTop; //元素外边框距离父元素内边框距离
var parent=e.offsetParent;
while(parent){
distance += parent.clientTop; //加上父元素边框宽度
distance += parent.offsetTop; //加上父元素外边框到下个包含元素内边框距离
parent = parent.offsetParent;
}
上面没有考虑一种非常稀有的案例,就是在body上设置了margin和border。这种情况非常少见,但如果真出现了,则必须注意。上面的code无法在所有的浏览器中工作。例如,chrome的body子元素的offsetTop是子元素到document最外边界的距离,body的margin,border都已经被算在其中,然而firefox则相反。
获取一个元素的内容区高度,应该使用:
var height = element.clientHeight>element.scrollHeight ? element.clientHeight : element.scrollHeight;
因为任何元素均可通过设置overflow来设置滚动条,所以任何元素均可设置scrollTop来使其滚动条滚动。 但最常见的还是根节点的scrollTop。因为大部分网页都只在最外层存在着一个滚动条。
最外层的滚动条位置的获取与设置在不同的浏览器不同:
FF+IE: document.documentElement.scrollTop
Chrome: document.body.scrollTop
坐标
原生JS
元素坐标存在两种:
-
以document最左上顶点为原点。获取元素在整个document中的位置。
-
以浏览器视窗(viewport)最左上顶点为原点。获取元素在视窗中的位置。
第一种坐标用于设置滚动条,例如,将滚动条滚动到element正好出现的位置。获取坐标的函数如下:
function getPositionInDoc(element) {
var position = {};
position.offsetY = (function(e){
var distance=e.offsetTop;
var parent=e.offsetParent;
while(parent){
distance += parent.clientTop;
distance += parent.offsetTop;
parent = parent.offsetParent;
}
return distance;
})(element);
position.offsetX = (function(e){
var distance=e.offsetLeft;
var parent=e.offsetParent;
while(parent){
distance += parent.clientLeft;
distance += parent.offsetLeft;
parent = parent.offsetParent;
}
return distance;
})(element);
return position;
}
将滚动条滚动到某个元素位置:
// chrome:
document.body.scrollTop = getPositionInDoc(element).offsetY;
// FF and IE:
document.documentElement.scrollTop = getPositionInDoc(element).offsetY;
第二种坐标是在浏览器视窗(viewport)的位置,这类坐标用于实现popup. 浏览器提供了一个方法getBoundingClientRect()。通过此方法可以获得元素坐标:
// rect = {
// top: 元素上外边框距离视窗顶部的距离, 负值表示上外边框超出了视窗上边界。
// bottom:元素下外边框距离视窗顶部的距离, 可以为负值。
// right: 元素右外边框距离视窗左边的距离, 可以为负值。
// left: 元素左外边框距离视窗左边的距离, 可以为负值。
// }
var rect = element.getBoundingClientRect();
可以通过第二种坐标,推导第一种坐标,而不需要再用循环的方式计算:
offsetY = rect.top + document.documentElement.scrollTop;
offsetX = rect.left + document.documentElement.scrollLeft;
反之也可。
JQuery
$.fn.width(/*optional*/ value) | 获取或设置width |
$.fn.innerWidth() | 获取width+padding |
$.fn.outerWidth(/*boolean*/includeMargin) | 获取width+padding+border (+margin) |
$.fn.height(/*optional*/ value) | 获取或设置height |
$.fn.innerHeight() | 获取height+padding |
$.fn.outerHeight(/*boolean*/includeMargin) | 获取height+padding+border (+margin) |
$.fn.offset(/*optional*/ coordination) | 获取元素相对于document的位置或移动元素到相应位置 |
$.fn.scrollLeft(/*optional*/ value) | 获取或设置scrollLeft |
$.fn.scrollTop(/*optional*/ value) | 获取或设置scrollTop |
维度
使用jQuery获取元素的高和宽非常简单,下图是从w3上获取的,此图解释了$.fn下的6个方法的含义
此外,如果想获取document的高度和宽度,则可以使用$(document).width() 和 $(document).height().
如果想获取视窗的大小,则可以使用$(window).width() 和 $(window).height().
坐标
获取元素在document中的坐标非常简单,只需要调用$(element).offset(). 此方法将返回{top, left}. 还可以使用offset({top, left})的方式,设置element的位置。element将会被设置position:relative.
获取元素在视窗(viewport)中的坐标, 则可以直接使用原生的getBoundingClientRect()。
获取scrollTop, scrollLeft和设置scrollTop,scrollLeft的方法
var scrollTop = $(document).scrollTop();
$(document).scrollTop(200); // scroll to 200px.
var scrollLeft = $(document).scrollLeft();
$(document).scrollLeft(100); // scroll to 100px.
dojo
dojo/dom-geometry
在dojo下,获取元素的位置和大小是由模块dojo/dom-geometry完成的,其几个常用方法:
position(node, includeScroll) |
当includeScroll为true时,返回相对于document的坐标, false则返回相对于视窗viewport的坐标。 返回值:{ w: 300: h: 150, x: 700, y: 900, } w:width+padding+border h: height+padding+border x,y为左上角外边框交点的坐标。 |
docScroll() |
返回值 {x: 10, y:10} 获取document滚动值。 |
其它更详细方法 |
可以参见dojo api |
dojo/window
而在模块dojo/window下,存在着关于viewport的方法:
getBox() | 获取视窗viewport的大小。宽度和高度。 返回值 {w: 100px, h:200px} |
scrollIntoView(node) | 将滚动条滚动到node能显示出来的位置。 |
使用方法如下:
require(['dojo/window', 'dojo/dom-geometry'], function(win, geom) {
var box = win.getBox();
var position = geom.position(element,false);
});
转载于:https://my.oschina.net/xpbug/blog/212094
上一篇: 吸引人的网页标题格式