欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DOM中的元素位置和大小的计算方法,含jquery和dojo方法

程序员文章站 2022-05-24 21:32:53
...

原生维度属性

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个方法的含义

DOM中的元素位置和大小的计算方法,含jquery和dojo方法

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