前端开发用javascript正确获取DOM元素的大小

2018-03-0800:52:26WEB前端开发Comments2,584 views字数 5930阅读模式

说明:本篇文章的代码都是在Mac操作系统的Chrome浏览器下进行的,因为部分代码的结果会因为操作系统和浏览器的不同而有所变化。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

作为一个前端开发者,需要经常与DOM元素打交道;也经常需要根据DOM元素的大小做一些事情。但是如何正确的获取DOM元素的大小呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

我们获取一个元素的大小,基本上是通过它的clientX, offsetX, scrollX属性来获取的(其中X表示widthheightlefttop)。具体属性可以看下表:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

clientXoffsetXscrollX
clientWidthoffsetWidthscrollWidth
clientHeightoffsetHeightscrollHeight
clientLeftoffsetLeftscrollLeft
clientTopoffsetTopscrollTop

我们首先来说一下clientX相关的属性,clientLeft表示的是一个元素的左边框的宽度;需要注意的是,如果元素里面的内容产生了垂直的滚动条,并且里面文字的书写方向是从右向左的话,那么clientLeft包括左边的滚动条的宽度(Windows系统下的Chrome,Firefox和Opera浏览器)。我们来实践一下: HTML部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

<div class="clientLeft">这是clientLeft</div>

CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.clientLeft {
    width: 100px;
    height: 100px;
    border-left: 6px solid black;
    padding: 15px;
    background-color: #999;
}

JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 辅助函数
const $ele = function (ele) {
    return document.querySelector(ele);
};
const $log = function () {
    console.log.apply(this, arguments);
};

// 测试clientX 属性
let clientLeft = $ele('.clientLeft');
$log('clientLeft的值是:' + clientLeft.clientLeft);

我们会看到控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

clientLeft的值是:6

然后我们修改一下元素clientLeft的CSS,让它的内容是从右向左排列的,然后让内容超出;我们来试验一下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.clientLeft {
    /* 省略上面已经写过的内容 */
    direction: rtl;
    /* 你需要将clientLeft的内容再增加一下,让里面的内容可以产生滑动 */
    overflow: scroll;
}

然后我们再看一下控制台的输出,这时候如果是Windows操作系统下的Chrome的话,就不会是6这个值了。因为笔者的电脑是Mac操作系统,所以控制台的打印还是6。 下面是我在windows系统里面的chrome浏览器的测试结果:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

前端开发用javascript正确获取DOM元素的大小 控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

clientLeft的值是:23

接下来我们来讨论一下clientTop属性,clientTop指的是元素上边框的宽度,我们来测试一下这个属性。 HTML部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

<div class="clientTop">这是clientTop,永远都不要放弃你的梦想</div>

CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.clientTop {
    width: 100px;
    height: 100px;
    margin-top: 10px;
    border-top: 6px solid black;
    padding: 15px;
    background-color: #999;
}

JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 测试clientTop 属性
let clientTop = $ele('.clientTop');
$log('clientTop的值是:' + clientTop.clientTop);

我们可以看到,控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

clientTop的值是:6

接下来我们来讨论clientWidthclientHeight属性的使用;这两个属性,一个是计算DOM元素的宽度,一个是计算高度的。不过这两个属性都只包含元素本身的宽高,以及元素的padding值,但是不包含元素的bordermargin的值,我们来测试一下。还需要注意的是,如果元素里面的内容超出了容器的宽度或者高度,产生了滑动条,那么也不会计算滑动条的部分。 HTML部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

<div class="clientWidth"> 这是clientWidth,永远都不要放弃你的梦想</div>

CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.clientWidth {
    width: 100px;
    height: 100px;
    margin-top: 10px;
    padding: 15px;
    background-color: #999;
}

JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 测试clientWidth 属性
let clientWidth = $ele('.clientWidth');
$log('clientWidth的值是:' + clientWidth.clientWidth);

我们会看到控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

clientWidth的值是:130

这是因为我们的CSS设置元素的宽度为100px,并且元素的padding值为15px;所以这个元素的clientWidth值就是100+15*2=130。接下来我们来测试一下内容超出容器宽度的情况。 CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.clientWidth {
    /* 以下部分是测试内容超出的情况 */
    white-space: nowrap;
    overflow: scroll;
}

当我们刷新页面,看到控制台的输出依然是:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

clientWidth的值是:130

这是因为clientWidth返回的是元素的可见部分的宽度,所以如果里面内容有超出的话,是不会计算超出的这部分内容的宽度的;clientHeight属性和clientWidth属性相似,这里就不在详细讲解了。 需要说明的是,如果上面的情况是在windows的chrome里面的话,那么clientWidth的值会变小,因为产生了垂直的滚动条;所以我们实际看到的clientWidth部分变小了,实际就是原来的值减去垂直滑动条的宽度;所以以后我们在开发的时候也需要多注意这些问题。 下图是我在windows上面的chrome上测试的一部分截图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

前端开发用javascript正确获取DOM元素的大小文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

前端开发用javascript正确获取DOM元素的大小文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

关于元素的clientX相关的属性我们暂时就先介绍到这里,接下来我们来介绍DOM元素的offsetX相关的属性。在讲解这些属性之前我们需要知道一个元素的offsetParent表示的是什么,详细的解释可以看这里 HTMLElement.offsetParent ,所谓的offsetParent指的就是包含当前元素的最近的定位元素。如果没有定位的元素,那么就是最近的tabletable cell或者根元素(标准模式下为html;quirks模式下为body)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

我们来测试一下一个元素的offsetParent属性,如下所示: HTML部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

<div class="testWrapper">
    <div class="test">用来测试test的offsetParent元素</div>
</div>

CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.testWrapper {
    margin-top: 15px;
    position: relative;
}
// 测试offsetParent 属性
let test = $ele('.test');
let testWrapper = $ele('.testWrapper');
$log('test的offsetParent的值是:', test.offsetParent === testWrapper);

控制台的打印结果如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

test的offsetParent的值是: true

如果不把testWrapper元素的position属性设置为relative或者absolute的话,那么testoffsetParent属性就不再是testWrapper了。 接下来我们来研究一下offsetLeftoffsetTop这两个属性的值,其中offsetLeft表示当前元素的左上角距离它的offsetParent元素节点的左边界的距离;而offsetTop表示的是当前元素的左上角距离它的offsetParent元素节点的上边界的距离。接下来我们来测试一下: CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.testWrapper {
    margin-top: 15px;
    position: relative;
    width: 200px;
    height: 200px;
    padding: 10px;
    background-color: #999999;
    border: 3px solid #333;
}
.test {
    width: 80px;
    height: 80px;
    float: right;
    padding: 5px;
    background-color: #ccff33;
    margin-top: 36px;
    border: 8px solid #333;
}

JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 测试offsetLeft属性和offsetTop属性
$log('test的offsetLeft的值是:' + test.offsetLeft);
$log('test的offsetTop的值是:' + test.offsetTop);

控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

test的offsetLeft的值是:104
test的offsetTop的值是:46

因为test是向右浮动的,所以testoffsetLeft的值就是testWrapper的宽度加上左边的padding值,然后减去test的整个宽度(包括borderpadding的值),也就是200 + 10 - (80 + 5 x 2 + 8 x 2) = 104,相应的offsetTop的值就是36 + 10 = 46marginTop的值加上testWrapperpaddingTop的值)。 接下来我们来研究一下offsetWidthoffsetHeight属性,与clientWidthclientHeight不同的是,offsetWidthoffsetHeight不仅包含元素本身CSS设置的宽高,元素内部的padding值;还包含元素的border的值,如果内部内容产生了滑动,还包括垂直滑动条的宽度;我们来测试一下。 HTML部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

<div class="offsetWidth"> 这是offsetWidth,永远都不要放弃你的梦想</div>

CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.offsetWidth {
    margin-top: 15px;
    width: 100px;
    height: 100px;
    padding: 8px;
    overflow: scroll;
    border: 9px solid black;
}

JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 测试offsetWidth属性
let offsetWidth = $ele('.offsetWidth');
$log('offsetWidth的值是:' + offsetWidth.offsetWidth);

控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

offsetWidth的值是:134

这个值是由元素的width值,padding值以及border值相加得来的;也就是100 + 8 x 2 + 9 x 2 = 134。相应的offsetHeight值也是如此,这里就不在演示了。 接下来我们要研究的是scrollX相关的属性,首先是scrollLeft或者scrollTop属性;这两个属性适用于元素内部有滑动的情况,我们来测试一下scrollLeft属性。 HTML部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

<div class="scrollLeft">这是scrollLeft,永远都不要放弃你的梦想</div>

CSS部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

.scrollLeft {
    width: 100px;
    height: 100px;
    margin-top: 15px;
    white-space: nowrap;
    overflow: scroll;
    border: 3px solid  black;
}

JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 测试scrollLeft属性
let scrollLeft = $ele('.scrollLeft');
$log('scrollLeft的值是:' + scrollLeft.scrollLeft);
// 修改scrollLeft的值
scrollLeft.scrollLeft = 10;
$log('scrollLeft的值是:' + scrollLeft.scrollLeft);

我们可以看到控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

scrollLeft的值是:0
scrollLeft的值是:10

在刚开始,因为内容没有进行滑动,所以初始值是0,但是当我们改变了scrollLeft的值的时候,我们会发现里面内容向左移动,并且scrollLeft值也变成了我们修改的值。因为scrollTopscrollLeft相似,这里就不再进行演示。 接下来我们来研究一下scrollWidthscrollHeight属性;因为这两个属性比较类似,所以我们就只测试一下scrollWidth属性。我们接着上面的例子进行测试。 JavaScript部分如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

// 测试scrollWidth属性的值
$log('scrollWidth的值是:' + scrollLeft.scrollWidth);

我们会看到控制台的输出如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

scrollWidth的值是:294

因为我们的元素本身的宽度只有100 + 3 x 2 = 106,但是控制台却输出了294,这里要说明一下,如果元素内部的内容没有超出元素的宽度,那么scrollWidth的值就是这个元素的clientWidth宽度;如果超出了元素的宽度,那么就是元素内容本身的宽度。 到此为止我们基本上把与一个元素大小有关的属性都讲解了一下,但是需要注意的是,因为操作系统和浏览器的实现的不同,元素的同一个属性值可能会不相同。 还有一些注意的点,我在下表中列了出来,我们来一起看一下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

属性读写是否整数
clientLeft只读取整(四舍五入)
clientTop只读取整(四舍五入)
clientWidth只读取整(四舍五入)
clientHeight只读取整(四舍五入)
offsetLeft只读取整(四舍五入)
offsetTop只读取整(四舍五入)
offsetWidth只读取整(四舍五入)
offsetHeight只读取整(四舍五入)
scrollLeft读写取整(四舍五入)
scrollTop读写取整(四舍五入)
scrollWidth只读取整(四舍五入)
scrollHeight只读取整(四舍五入)

文章的在线示例可以在 这里 查看或者查看 源代码 ;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/1290.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/1290.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定