获取Dom元素的X/Y坐标(2)

作者:zhusun 来源:Koubei UED 时间:2009-10-10 12:49:00 

将ClientRect对象的left、top属性分别加上scrollLeft和scrollTop,就能获取Dom元素的X/Y坐标了。但对于IE8之前的IE版本在很多情况下要对这个值进行一些调整,有三种情况,下面来分别看一下:

1.IE6的标准模式下不需要调整;

2.所有怪异模式下为取document的当前borderLeftWidth和borderTopWidth值做调整,分别加在X/Y坐标值上;

3.其他的情况都分别在X/Y坐标值上加上2;

样就可以获取最后准确的X/Y坐标了。如果所有的浏览器都能如此就好了,可惜有些浏览器(FF2、Safari)不支持getBoundingClientRect方法。需要通过一级级查找和计算offsetParent来获取X/Y坐标值。这里首先介绍什么是元素的offsetParent属性。

offsetParent属性是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过CSS定位的与容器元素。首先说明一下CSS定位,是指对元素设置position属性为absolute、relative或fixed(IE6除外),还有一个问题是元素在table元素中时会有不同的情况。

下面是我的一些归纳,不全之处望大家指出:

1.元素不在table元素中,且元素及其所有上级元素都未进行CSS定位时,这个元素的offsetParent属性为根元素(Body);

2.元素本身没进行CSS定位,而出现在table中或有上级元素进行了CSS定位,那么当向上先达到TD元素时该元素的offsetParent属性为TD元素;当向上先达到进行了CSS定位的上级元素时该元素的offsetParent属性为该上级元素;

3.无论元素在不在table中,只要元素本身进行了CSS定位,有上级元素进行了CSS定位的则元素的offsetParent属性为该上级元素,没有上级素进行了CSS定位的则元素的offsetParent属性为根元素;

知道了offsetParent属性的含义,就可以通过offsetParent属性来一级级的计算X/Y坐标了。一种比较简单的while循环:

    var node;/*求坐标的元素*/
    var xy=[];/*保存XY坐标*/
    while ((node = node.offsetParent)) {
      xy[0] += node.offsetLeft;
      xy[1] += node.offsetTop];
    }

通过这一个循环就能累计元素每级offsetParent属性元素的偏移量,但这个偏移量在累加的过程中没有计算每级父元素有滚动条的情况,最后还要同getBoundingClientRect方法一样加上页面滚动值(这里scrollLeft和scrollTop)。现在先来累计计算元素每上级元素的滚动条情况,首先判断元素本身是不是设置了position为fixed:

1.设置了则不用计算每上级元素的滚动条情况,但需要对Opera和其他浏览器做区分,Opera浏览器减去scrollLeft和scrollTop xy[0] -= scrollLeft;xy[1] -= scrollTop;,其他情况是加上scrollLeft和scrollTop。

xy[0] += scrollLeft;xy[1] += scrollTop;2.未设置时就需要累计计算元素每上级元素的滚动条,通过一个循环里累加:

while ((node = node.parentNode) && node.tagName) {
  scrollTop = node.scrollTop;
  scrollLeft = node.scrllLeft;
  if (scrollTop || scrollLeft) {
    xy[0] -= scrollLeft;
    xy[1] -= scrollTop;
  }
}

最后机上页面滚动值

xy[0] += scrollLeft;xy[1] += scrollTop;

这样最后就可以在不支持getBoundingClientRect方法的浏览器下获取元素的X/Y坐标了。
最后总结一下,如果浏览器支持getBoundingClientRect方法,通过该方法再加上页面滚动条的偏移就能获取元素的X/Y了(不同浏览器需要微调),如果不支持getBoundingClientRect方法,则需要通过循环该元素的每级offsetParent属性来累计偏移量,再通过每个父级元素的滚动条来调整,最后再加上页面滚动条的偏移来获取元素的X/Y坐标。获取X/Y坐标的方式还有很多,可能不尽相同,我这里主要是基于YUI里面的思想和方法。不全之处望大家指正~

标签:dom,坐标,框架,对象
0
投稿

猜你喜欢

  • 给Notepad++换主题

    2009-05-04 14:43:00
  • 用Python的SimPy库简化复杂的编程模型的介绍

    2023-06-19 16:55:45
  • XHTML1.0规范:您是否为img图片标签赋予alt属性

    2009-09-21 11:11:00
  • Oracle性能究极优化 下

    2010-07-30 13:25:00
  • python 2.7.13 安装配置方法图文教程

    2023-11-13 11:54:37
  • 从pandas一个单元格的字符串中提取字符串方式

    2022-10-14 21:24:35
  • VScode中不同目录间python库函数的调用

    2021-03-16 00:24:38
  • 用Dreamweaver MX巧妙格式化表格

    2008-03-18 16:39:00
  • 13个PHP函数超实用

    2024-03-21 18:57:50
  • 对Python进行数据分析_关于Package的安装问题

    2021-07-29 17:23:42
  • Python利用pdfplumber实现读取PDF写入Excel

    2023-02-21 01:08:57
  • Python 数据结构之队列的实现

    2021-11-28 15:27:26
  • python 多进程并行编程 ProcessPoolExecutor的实现

    2023-10-23 14:41:56
  • 20行Python代码实现视频字符化功能

    2023-01-08 21:17:02
  • 使用base64对图片的二进制进行编码并用ajax进行显示

    2024-05-02 16:18:24
  • opera img onload重复执行

    2008-01-17 12:01:00
  • Python操作MySQL MongoDB Oracle三大数据库深入对比

    2024-01-13 21:48:00
  • asp网上购物车实例代码

    2007-10-03 13:43:00
  • Django中auth模块用户认证的使用

    2023-02-08 13:49:58
  • Python多线程threading和multiprocessing模块实例解析

    2023-05-11 13:30:51
  • asp之家 网络编程 m.aspxhome.com