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

元素坐标存在两种:

  1. 以document最左上顶点为原点。获取元素在整个document中的位置。

  2. 以浏览器视窗(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个方法的含义

220326_8coM_254689.png

此外,如果想获取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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值