详解DOM对象中clientWidth、offsetWidth等属性
我们有时需要获得鼠标在某盒子中的位置,或者是随意移动某盒子的位置,在这些场景中我们可能经常需要用到clientWidth、offsetWidth、offsetTop啊等等。但是对于初学者来说(包括我),看到这些就头疼,因为感觉意思都相近,但作用却不同,所以今天天我就来捋一捋,搞清楚,后面好干活。好吧,废话不多说,开始吧。
先上一下示例代码,下面要用到。
HTML:
CSS:
JS:
一、clientWidth和clientHeight
clientWidth和clientHeight的计算方式是一样的,只不过一个为水平方向,一个为垂直方向,接下来我就只用clientWidth来说明情况。clientWidth与只与元素有关,它的计算方式如下。
clientWidth=width(样式中设置的)+左padding+右padding-垂直滚动条宽度。
同理,clientHeight=height+顶部padding+底部padding-水平滚动条宽度。
以下是示例(div#sub-content没有添加margin):
输出:
clientWidth:200+10+10-17(滚动条宽度)=203
二、offsetWidth和offsetHeight
offsetWidth与offsetHeight有个特点,就是这两个属性的值只与该元素有关,与周围元素(父级和子级元素无关)。
它们的大小取决于元素的宽高、padding以及边框border,有无滚动条都没有影响,下面是他们的计算方式。
offsetWidth=width(样式中设置的)+左右padding+左右border
offsetHeight=height(样式中设置的)+上下padding+上下border
以下是示例(#sub-content的高度改为100px):
输出:
三、offsetParent
也许你看到这里会觉得奇怪,怎么突然冒出个offsetParent出来,先别急,后面我要讲offsetTop和offsetLeft,因为这两个和offsetParent离不开关系,所以我就先好后介绍一下offsetParent。
offsetParent属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过CSS定位的容器元素。 如果这个容器元素未进行CSS定位, 则offsetParent属性的取值为根元素的引用。
总的来说两条规则:
1、如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),offsetParent为body。
2、如果当前元素的父级元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个父级元素。
我们以上面代码为例,可以看到div#content并没有设置定位position,接下来我们要查找div#sub-content的offsetParent,
看下面演示。
输出:
当div#content添加定位position:reletive;样式,并将tagName换为id时
输出:
四、offsetTop和offsetLeft
offsetTop和offsetLeft这两个属性和offsetWidth和offsetHeight不同的是,它们受到offsetParent的影响(offsetParent上面有讲),
MSDN上对offsetLeft的定义是:
The HTMLElement.offsetLeft read-only property returns the number of pixels that the upper left corner of the current element is offset to the left within the HTMLElement.offsetParent node.
指的是offsetLeft只读属性返回当前元素左上角在offsetParent节点内向左偏移的像素数。
从这个定义中我们可以明确地知道offsetLeft与当前元素的margin-left和offsetParent的padding-left有关。也就是说应该是:
offsetLeft=(offsetParent的padding-left)+(中间元素的offsetWidth)+(当前元素的margin-left)。
offsetTop=(offsetParent的padding-top)+(中间元素的offsetHeight)+(当前元素的margin-top)。
我们为上面代码的div#content添加一个子元素div#sub1
并添加样式(说明以下,div#sub-content的高度被我改成了50px)
演示图如下
可以知道,div#sub-content的offsetParent并不是div#content,而是BODY,我们打印一下offsetTop
输出:
112=20(div#content margin-top)+10(div#content border-top)+10(div#content padding-top)+52(#divsub1 height+border) + 20(div#sub-content margin-top)
接下来我们为div#content添加定位position:relative;
最后输出:
可以知道div#sub-content的offsetParent变成div#content。
五、scrollWidth和scrollHeight
scrollWidth和scrollHeight这两个属性用来获取指定元素内容层的真实宽度和高度.
当不存在水平或垂直滚动条时,scrollWidth和scrollHeight等于clientWidth和clientHeight,
当存在水平或垂直滚动条时,请看下面演示(将div#sub-contetn的height设为300px)
输出:
可以看到图中存在垂直方向的滚动条
scrollWidth=clientWidth=width+左右padding-滚动条宽度=203
scrollHeight=20(div#content padding)+40(div#sub-content margin)+20(div#sub-content border)+20(div#sub-content padding)+300(div#sub-content height)=400
可以看出来其实scrollWidth和scrollHeight等于clientWidth和clientHeight还是有很大联系的,当内容层的高宽度超过指定元素的高宽度时,scrollWidth和scrollHeight还得在clientWidth和clientHeight的基础上加上内容层增加高度以及减去相应的滚动条宽度。
也可以这样理解,scrollWidth和scrollHeight即可视区域宽高度+被隐藏区域宽高度。
六、scrollTop和scrollLeft
scrollLeft:对象的最左边到对象在当前窗口显示的范围内的左边的距离,即在出现了横向滚动条的情况下,滚动条拉动的距离。
scrollTop对象的最顶部到对象在当前窗口显示的范围内的顶边的距离,即在出现了纵向滚动条的情况下,滚动条拉动的距离。
下面的图有些复杂,但可以稍微看看。
最近开了个公众号用于推送前端学习总结,有兴趣的可以关注一下。
详解DOM对象中clientWidth、offsetWidth等属性相关推荐
- 详解Android布局中gravity与layout_gravity属性
在android布局中,我们经常会用到"重心"-gravity这个属性.但是gravity有不同的类型: gravity layout_gravity 相对布局中的layout_c ...
- 详解jQuery对象与DOM对象的相互转换
一直以来对于通过jQuery方式获取的对象,却不能直接使用JavaScript的方法很不理解,现在知道,原来jQuery获得的对象并不和我们平时使用getElementById获得的对象一样.所以一些 ...
- es6字符串添加html标签,JavaScript_详解JavaScript ES6中的模板字符串,在 ES6 中引入了一种新的字符 - phpStudy...
详解JavaScript ES6中的模板字符串 在 ES6 中引入了一种新的字符串字面量 - 模板字符串,除了使用反引号 (`) 表示,它们看上去和普通的字符串没有什么区别.在最简单的情况下,他们就是 ...
- js模板字符串自定义类名_详解JavaScript ES6中的模板字符串
这篇文章主要介绍了详解JavaScript ES6中的模板字符串,JS的ES6版本带来诸多简洁化方面的重大改进,需要的朋友可以参考下 在 ES6 中引入了一种新的字符串字面量 - 模板字符串,除了使用 ...
- php开发面试题---php面向对象详解(对象的主要三个特性)
php开发面试题---php面向对象详解(对象的主要三个特性) 一.总结 一句话总结: 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为. 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸 ...
- java 泛型详解、Java中的泛型方法、 java泛型详解
本文参考java 泛型详解.Java中的泛型方法. java泛型详解 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即& ...
- java按钮权限控制_详解Spring Security 中的四种权限控制方式
Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Se ...
- java jdbc 详解_JDBC概述及详解各个对象
JDBC(Java DataBase Connectivity)详解 一.概念: JDBC是一种可执行SQL语句的JavaAPI,Java数据库链接,Java语言操做数据库mysql 二.本质: JD ...
- JavaSE学习笔记 详解Set集合中实现类:LinkedHashSet以及TreeSet
详解Set集合中实现类:LinkedHashSet以及TreeSet 1.LinkedHashSet概述 2.TreeSet概述 2.1 自然排序 2.1.1 TreeSet存储常见引用数据类型 2. ...
最新文章
- Bootstrap组件_分页
- 实战 | Element UI 父子组件传值与事件绑定(正向)
- 网络协议分析(Network Protocol Analysis)之点到链路控制协议LCP
- Java8 改进的匿名内部类:
- 小程序发布上线流程_小程序如何发布?微信小程序发布流程很简单
- Android 选择文件(调用系统文件管理器)
- Ubuntu 的千千静听
- Linux 内核配置项详解 myimx6
- 使用母版页实现页面布局
- 老挑毛u盘一键装系统计算机意外地,u盘装系统 重装Win7系统出现提示计算机意外的重新启动或遇到错误怎么处理 我已经删除了所有分...
- CSAPP 第二章家庭作业2.70
- python禅语_42:对象、类、以及从属关系
- Web自动化测试(Selenium自动化测试框架)
- 计算机四级网络工程师真题答案解析,计算机四级网络工程师历年真题及答案
- 几个开源的运维管理系统介绍
- Python学习1--Python基础
- Android 调用谷歌语音识别:获取识别结果,进行文字输出
- 什么样的程序员才是牛逼的程序员
- Android menu属性详解
- 卡特尔世界杯来了,只喝精酿啤酒不玩望京扑克,其实也是一种缺失