用JavaScript获取DOM元素位置和尺寸大小的方法

在一些复杂的页面中经常会用JavaScript处理一些DOM元素的动态效果,这种时候我们经常会用到一些元素位置和尺寸的计算,浏览器兼容性问题也是不可忽略的一部分,要想写出预想效果的JavaScript代码,我们需要了解一些基本知识。

基础概念

为了方便理解,我们需要了解几个基础概念,每个HTML元素都有下列属性



















offsetWidth

clientWidth

scrollWidth

offsetHeight

clientHeight

scrollHeight

offsetLeft

clientLeft

scrollLeft

offsetTop

clientTop

scrollTop


为了理解这些属性,我们需要知道HTML元素的实际内容有可能比分配用来容纳内容的盒子更大,因此可能会出现滚动条,内容区域是视口,当实际内容比视口大的时候,需要把元素的滚动条位置考虑进去。

1. clientHeight和clientWidth用于描述元素内尺寸,是指 元素内容+内边距 大小,不包括边框(IE下实际包括)、外边距、滚动条部分

2. offsetHeight和offsetWidth用于描述元素外尺寸,是指 元素内容+内边距+边框,不包括外边距和滚动条部分

3. clientTop和clientLeft返回内边距的边缘和边框的外边缘之间的水平和垂直距离,也就是左,上边框宽度

4. offsetTop和offsetLeft表示该元素的左上角(边框外边缘)与已定位的父容器(offsetParent对象)左上角的距离

5. offsetParent对象是指元素最近的定位(relative,absolute)祖先元素,递归上溯,如果没有祖先元素是定位的话,会返回null

写个小例子方便理解


代码如下:

<div id="divParent" style="padding: 8px; background-color: #aaa; position: relative;">
        <div id="divDisplay" style="background-color: #0f0; margin: 30px; padding: 10px;
            height: 200px; width: 200px; border: solid 3px #f00;">
        </div>
    </div>

代码如下:

<script type="text/javascript">
        var div = document.getElementById('divDisplay');

var clientHeight = div.clientHeight;
        var clientWidth = div.clientWidth;
        div.innerHTML += 'clientHeight: ' + clientHeight + '<br/>';
        div.innerHTML += 'clientWidth: ' + clientWidth + '<br/>';

var clientLeft = div.clientLeft;
        var clientTop = div.clientTop;
        div.innerHTML += 'clientLeft: ' + clientLeft + '<br/>';
        div.innerHTML += 'clientTop: ' + clientTop + '<br/>';

var offsetHeight = div.offsetHeight;
        var offsetWidth = div.offsetWidth;
        div.innerHTML += 'offsetHeight: ' + offsetHeight + '<br/>';
        div.innerHTML += 'offsetWidth: ' + offsetWidth + '<br/>';

var offsetLeft = div.offsetLeft;
        var offsetTop = div.offsetTop;
        div.innerHTML += 'offsetLeft: ' + offsetLeft + '<br/>';
        div.innerHTML += 'offsetTop: ' + offsetTop + '<br/>';

var offsetParent = div.offsetParent;
        div.innerHTML += 'offsetParent: ' + offsetParent.id + '<br/>';
    </script>

效果如图

从图中我们可以看到,clientHeight就是div的高度+上下各10px的padding,clientWidth同理

而clientLeft和ClientTop即为div左、上边框宽度

offsetHeight是clientHeight+上下个3px的边框宽度之和,offsetWidth同理

offsetTop是div 30px的 maggin+offsetparent 8px的 padding,offsetLeft同理

6. scrollWidth和scrollHeight是元素的内容区域加上内边距加上溢出尺寸,当内容正好和内容区域匹配没有溢出时,这些属性与clientWidth和clientHeight相等

7. scrollLeft和scrollTop是指元素滚动条位置,它们是可写的

下面写个简单例子理解

代码如下:

<div id="divParent" style="background-color: #aaa; padding:8px; border:solid 7px #000; height:200px; width:500px; overflow:auto;">
        <div id="divDisplay" style="background-color: #0f0; margin: 30px; padding: 10px;
            height: 400px; width: 200px; border: solid 3px #f00;">
        </div>
    </div>

代码如下:

<script type="text/javascript">
        var divP = document.getElementById('divParent');
        var divD = document.getElementById('divDisplay');

var scrollHeight = divP.scrollHeight;
        var scrollWidth = divP.scrollWidth;
        divD.innerHTML += 'scrollHeight: ' + scrollHeight + '<br/>';
        divD.innerHTML += 'scrollWidth: ' + scrollWidth + '<br/>';
    </script>

在FireFox和IE10(IE10以下版本盒模型和W3C标准不一致,不加讨论,兼容性问题下面会介绍到)下得到结果scrollHeight: 494,而在Chrome和Safari下得到结果scrollHeight: 502,差了8px,根据8可以简单推测是divParent的padding,来算一下是不是

我们可以看看它们的结果是怎么来的,首先scrollHeight肯定包含了divDisplay所需的高度 400px的高度+上下各10px的padding+上下各3px的border+上下各30px的margin,这样

400+10*2+3*2+30*2=486

这样486+8=494, 486+8*2=502果真是这样,在FireFox和IE10下没有计算下padding

有了这些基础知识后,我们就可以计算元素的位置和尺寸了。

相对于文档与视口的坐标

当我们计算一个DOM元素位置也就是坐标的时候,会涉及到两种坐标系,文档坐标和视口坐标。

我们经常用到的document就是整个页面部分,而不仅仅是窗口可见部分,还包括因为窗口大小限制而出现滚动条的部分,它的左上角就是我们所谓相对于文档坐标的原点。

视口是显示文档内容的浏览器的一部分,它不包括浏览器外壳(菜单,工具栏,状态栏等),也就是当前窗口显示页面部分,不包括滚动条。

如果文档比视口小,说明没有出现滚动,文档左上角和视口左上角相同,一般来讲在两种坐标系之间进行切换,需要加上或减去滚动的偏移量(scroll offset)。

为了在坐标系之间进行转换,我们需要判定浏览器窗口的滚动条位置。window对象的pageXoffset和pageYoffset提供这些值,IE 8及更早版本除外。也可以通过scrollLeft和scrollTop属性获得滚动条位置,正常情况下通过查询文档根节点(document.documentElement)来获得这些属性值,但在怪异模式下必须通过文档的body上查询。

代码如下:

function getScrollOffsets(w) {
            var w = w || window;
            if (w.pageXoffset != null) {
                return { x: w.pageXoffset, y: pageYoffset };
            }
            var d = w.document;
            if (document.compatMode == "CSS1Compat")
                return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
            return { x: d.body.scrollLeft, y: d.body.scrollTop };
        }

有时候能够判断视口的尺寸也是非常有用的

代码如下:

function getViewPortSize(w) {
            var w = w || window;
            if (w.innerWidth != null)
                return { w: w.innerWidth, h: w.innerHeight };
            var d = w.document;
            if (document.compatMode == "CSS1Compat")
                return { w: d.documentElement.clientWidth, h: d.documentElement.clientHeight };
            return { w: d.body.clientWidth, h: d.body.clientHeight };
        }

文档坐标

任何HTML元素都拥有offectLeft和offectTop属性返回元素的X和Y坐标,对于很多元素,这些值是文档坐标,但是对于以定位元素后代及一些其他元素(表格单元),返回相对于祖先的坐标。我们可以通过简单的递归上溯累加计算

代码如下:

function getElementPosition(e) {
            var x = 0, y = 0;
            while (e != null) {
                x += e.offsetLeft;
                y += e, offsetTop;
                e = e.offsetParent;
            }
            return { x: x, y: y };
        }

尽管如此,这个函数也不总是计算正确的值,当文档中含有滚动条的时候这个方法就不能正常工作了,我们只能在没有滚动条的情况下使用这个方法,不过我们用这个原理算出一些元素相对于某个父元素的坐标。

视口坐标

计算视口坐标就相对简单了很多,可以通过调用元素的getBoundingClientRect方法。方法返回一个有left、right、top、bottom属性的对象,分别表示元素四个位置的相对于视口的坐标。getBoundingClientRect所返回的坐标包含元素的内边距和边框,不包含外边距。兼容性很好,非常好用

元素尺寸

由上面计算坐标方法,我们可以方便得出元素尺寸。在符合W3C标准的浏览器中getBoundingClientRect返回的对象还包括width和height,但在原始IE中未实现,但是通过返回对象的right-left和bottom-top可以方便计算出。

(0)

相关推荐

  • JS和JQUERY获取页面大小,滚动条位置,元素位置(示例代码)

    js与jquery获得页面大小.滚动条位置.元素位置 复制代码 代码如下: //页面位置及窗口大小 function GetPageSize() {var scrW, scrH; if(window.innerHeight && window.scrollMaxY) {    // Mozilla    scrW = window.innerWidth + window.scrollMaxX;    scrH = window.innerHeight + window.scrollMaxY

  • JS实现设置ff与ie元素绝对位置的方法

    本文实例讲述了JS实现设置ff与ie元素绝对位置的方法.分享给大家供大家参考,具体如下: function Show_menu(liid,divid) { var li=document.getElementById(liid); var div=document.getElementById(divid); div.style.left=getLeft(li)+140+'px'; div.style.top= getTop(li)+'px'; var tt=div.style.top; div

  • JavaScript中计算网页中某个元素的位置

    由于项目的需要,测试中需要对网页元素进行截图,以确保它看上去没有问题.之前我写过一篇文章介绍过一种方法,先使用 WebDriver 进行全屏截图,然后根据目标元素(DOM Element)所在的位置,再对截下来的图片进行剪裁,保留我们需要的位置即可. 那段代码一直都工作得很好,直到我知道了一个东西:iframe.iframe(普通的 frame 也是一样的,不过 frame 现在不太常见,这里只用 iframe 举例)中的内容被视为一个独立的网页,连 Window 对象也是和它的父级网页分开的.

  • Javascript中找到子元素在父元素内相对位置的代码

    经过自己一晚上尝试,貌似找到了一个方法. 现在脑袋还糊涂,先记下来,以后再分析. 复制代码 代码如下: // 找到子元素在父元素中的相对位置 function getElementTop(element){ var el = (typeof element == "string") ? document.getElementById(element) : element; if (el.parentNode === null || el.style.display == 'none')

  • 在JS数组特定索引处指定位置插入元素的技巧

    如何在JS数组特定索引处指定位置插入元素? 需求: 将一个元素插入到现有数组的特定索引处.听起来很容易和常见,但需要一点时间来研究它. // 原来的数组 var array = ["one", "two", "four"]; // splice(position, numberOfItemsToRemove, item) // 拼接函数(索引位置, 要删除元素的数量, 元素) array.splice(2, 0, "three"

  • 用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数

    首先这个元素position为fixed top为(clientHeight-elem.offsetHeight)/2(即元素在浏览器的中间,这个是固定的) left为(clientWidht-主体宽度)/2+主体宽度+左边距,左边距可以设为正数,也可以为负数,如果为负数时的绝对值 等于 主体宽度+elem.offsetWidht,那么元素就刚好浮动在页面主体的左边,设置为0时,刚好浮动在页面主体的右边 但是万恶的ie6不支持css中fixed属性,好在ie6可以通过expresion表达式来解

  • js获取元素相对窗口位置的实现代码

    JS获取元素的offsetTop,offsetLeft等属性 obj.clientWidth //获取元素的宽度 obj.clientHeight //元素的高度 obj.offsetLeft //元素相对于父元素的left obj.offsetTop //元素相对于父元素的top obj.offsetWidth //元素的宽度 obj.offsetHeight //元素的高度 区别: clientWidth = width + padding clientHeight = height + p

  • javascript实现拖动元素交换位置

    本文实例讲述了javascript实现拖动元素交换位置的代码.分享给大家供大家参考.具体如下: 实现目标:可拖动元素拖动到另外一个元素位置的时候,互相交换位置. 启发来源:最初形式是网上看到的一个拼图小游戏. 运行效果截图如下: 具体代码如下: 代码: body,ul,li{margin:0;padding:0;} ul{list-style: none;} body{font:13px/1.5 Tahoma;} #box{position:relative;width:435px;height

  • JS实现随页面滚动显示/隐藏窗口固定位置元素

    窗口固定位置显示元素,当页面高度大于某高度,并且页面向下滚动时,显示该元素:当页面位置小于某高度,或者页面向上滚动时,隐藏该元素. 先给大家展示下效果图: 1.html <p id="selected-case-count"><span class='form-control'>已选: <span class="casecount">0</span></span></p> 2.css p#sel

  • 在JS数组特定索引处指定位置插入元素

    很多与数组有关的任务听起来很简单,但实际情况并不总是如此,而开发人员在很多时候也用不到他.最近我碰到了这样一个需求: 将一个元素插入到现有数组的特定索引处.听起来很容易和常见,但需要一点时间来研究它. // 原来的数组 var array = ["one", "two", "four"]; // splice(position, numberOfItemsToRemove, item) // 拼接函数(索引位置, 要删除元素的数量, 元素) ar

  • JavaScript DOM元素尺寸和位置

    一 获取元素的CSS大小 1.通过style内联获取元素的大小 复制代码 代码如下: var box = document.getElementById('box');    // 获得元素;      box.style.width;                             // 200px;      box.style.height;                            // 200px; // PS:style获取只能取到行内style属性的CSS样式中

  • JavaScript中的noscript元素属性位置及作用介绍

    一.<script>元素属性 向XHTML页面中插入JavaScript的主要方法,就是使用<script>元素,该元素有5个属性分别为charset.defer.language.src.type,经常使用的是type.src.defer这三个. 1.type属性的值一般都是text/javascript,该属性是必须的,<script type="text/javascript"/>. 2.src属性的值是*.js外部文件,该属性是可选的,<

随机推荐