文档章节

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

xpbug
 xpbug
发布于 2014/03/24 23:51
字数 1599
阅读 2307
收藏 4

原生维度属性

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

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


© 著作权归作者所有

xpbug
粉丝 304
博文 102
码字总数 125336
作品 0
浦东
程序员
私信 提问
mootools,jquery,dojo

最近,我开始关注Dojo了,Dojo是一个强大的面向对象JavaScript框架,既然我那么喜欢MooTools,也没理由不喜欢Dojo。与Dojo相比我对MooTools 和 jQuery 是比较熟的。这并不重要,不管使用什么样...

水稻
2015/01/20
0
0
初看jQuery,比较dojo与jQuery的不同点

以下观点是建立在我初看jQuery,但并没有对jQuery详细理解的情况下。 可能随着后面对jQuery的使用,而增加更深的了解。也可能发现我当初的观点是错误的。 大体浏览了一下jQuery的文档,发现j...

xpbug
2012/08/18
0
0
jQuery中的宽度和高度计算

DOM中宽度高度: window的宽度高度:代表着浏览器的有效可见区域的宽度高度,即浏览器工具栏和任务栏之间的区域,它会随着最大化最小化或改变窗口尺寸的变化而变化,它代表着“视界”。 docu...

i33
2013/03/25
0
0
Dijit、ExtJS、jQuery UI 异同浅析

简介: 当今,各类 JavaScript 框架在前端开发中已经相当普及。Dojo、Ext jQuery 等主流 JavaScript 框架不仅提供了一系列核心 API 来屏蔽浏览器差异,简化 DOM 操作、增强 JavaScript 原生 ...

索隆
2012/02/21
0
0
Dojo 与 jQuery 综合比较分析

最近Dojo 和jQuery双双发布了最新的1.8版本,有着相同版本号的两个Javascript库也有许多核心的相同之处:相同的资源加载机制AMD、相同的选择 器 引擎Sizzle等。作为业界知名的Javascript库,...

鉴客
2012/07/09
12.4K
21

没有更多内容

加载失败,请刷新页面

加载更多

Protocol Buffers 简介

文档编辑和持续集成状态: 本文档的 Protocol Buffer 的中文文档使用的是 Asciidoctor 进行编排的 http://docs.ossez.com/protocol-buffers-docs/index.html(本 WIKI 中的内容将会与在线发布...

honeymoose
今天
4
0
uniapp + bootstrapvue 移动/PC 一套搞定 (一)配置bootstrapvue

1.准备文件 自己到DCloud官网: http://dcloud.io/ 去下载官方的IDE Hbuilder,新建一个空的uniapp项目即可。 uniapp框架自带优化的vue,我们仅仅需要准备以下三个文件: bootstrap.min.css ...

panyunxing
今天
12
0
Android Camera原理之camera service类与接口关系

camera service主要是指 frameworks/av/services/camera/下面的代码,最近在看这一块的代码,为了更好地理清这一块的代码,也为了后续学习camera方便一些,我觉得很有必要理一下这一块的整体...

天王盖地虎626
今天
6
0
Golang学习笔记

[TOC] Golang学习笔记 这个学习笔记是最早在1.初,版本左右的时候写的,和当前最新的版本可能会有较大的差异. 因为成文比较早,文章里面又有很多自己的见解,有些东西当时理解的不太透彻可能写错...

我爱吃炒鸡
今天
21
0
科技赋能成效显著!金融壹账通两大赋能项目荣获IDC大奖

7月19日,2019IDC中国未来金融论坛曁颁奖典礼于北京举办。由金融壹账通赋能的长春农商银行多人视频面审智能风控系统、包头农商银行互联网银行SaaS服务两大项目因在项目的创新性、技术领先性、...

IFTNews
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部