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; 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=" 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可以方便计算出。
JavaScript获取DOM元素位置和尺寸大小相关推荐
- uniapp vue获取dom元素位置和高度信息
我有一个标题,希望它的高度是动态变化的 <view :style="{height: height + 'px'}"><view id="title_i ...
- javascript中获取dom元素高度和宽度
javascript中获取dom元素高度和宽度的方法如下: 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight ...
- js中获取dom元素高度
目录 1.dom元素的宽高 2.鼠标事件中的常用高度宽度: 3. 总结: 4.参考博客: 1.dom元素的宽高 javascript中获取dom元素高度和宽度的方法如下: 网页可视区域宽: docum ...
- JS获取DOM元素的八种方法
什么是HTML DOM 文档对象模型(Document Object Model),是W3C组织推荐的处理可扩展置标语言的标准编程接口.简单理解就是HTML DOM 是关于如何获取.修改.添加或删除 ...
- 在指定的查找范围内获取DOM元素
在指定的查找范围内获取DOM元素 (1)功能描述 定义两个全局变量,其$objTmp0通过$(expression,[context])方法获取DOM元素div0,另外一个变量$objTmp1通过$( ...
- 获取DOM元素方法小结
在开发中不可避免的需要操作DOM,现在就来总结一下原生的获取DOM的API. getElementById() 该方法是最常用的通过元素的id属性来获取DOM元素的API,返回一个DOM元素. < ...
- JS获取DOM元素的方法
什么是HTML DOM 文档对象模型(Document Object Model),是W3C组织推荐的处理可扩展置标语言的标准编程接口.简单理解就是HTML DOM 是关于如何获取.修改.添加或删除 ...
- 获取dom元素的方法
在 JavaScript 中,获取 DOM 元素的方式有多种.下面列出了一些常用的方法: 1.用 document.getElementById() 方法:该方法需要传入一个参数,即要获取元素的 id ...
- 获取DOM元素后,对NodeList的遍历的几种方法
在使用原生方法或者jquery方法获取DOM元素后,想像正常使用数组的方法对其遍历时,发现一些数组的遍历方法使用不了,如map ,push , pop等方法.使用后报错:.map is not a f ...
最新文章
- 2018高中计算机会考知识点,2018高中物理会考知识点总结
- mybatis的简单查询用语句吗_FILTER函数你用过吗?一对多查询与自动筛选,用它都能轻松搞定...
- Android使用ImageView显示网络图片
- linux中GDB详细使用手册
- 基于环信的仿QQ即时通讯的简单实现
- java getabsolutepath,详谈java中File类getPath()、getAbsolutePath()、getCanonical的区别
- jquery.cookie.js 使用小结
- mysql 自定义函数function,函数和存储过程的区别
- linux mysql数据库备份并删除前一分钟的数据
- 八、spring生命周期之BeanPostProcessor
- 怎么在长方体上挖孔_华为P50将至,颜值升级!用上和三星旗舰一样的中置挖孔屏?...
- 【实用工具】adb检测android设备
- 【原创】洛谷 LUOGU P3371 【模板】单源最短路径
- python的标准数据类型_Python中的标准数据类型
- 网络机顶盒固件增删预装APP步骤
- 笔记 || css字体word字体大小对照表
- 简单嵌入式系统软件架构
- linux网络lo是什么,Linux基礎必懂:eth0,eth1,eth2,lo是什么意思?
- 1-以太坊私钥公钥地址生成
- matlab gui 作者,MATLAB GUI设计学习手记(第4版)
热门文章
- 网上银行跨行转账收费最高相差25倍 省钱有窍门
- vue transition动画
- 为什么plotly被称为“有史以来最牛逼”可视化神器?
- NodeJs开发微信公众号(一)
- SAS学习笔记之《SAS编程与数据挖掘商业案例》(4)DATA步循环与控制、常用全程语句、输出控制...
- SunDay天气——开放源代码
- HTML Add-on HTML 查看器/编辑器查看器
- python-django框架中使用docker和elasticsearch配合实现搜索功能
- 前端:JS中JSON对象和String转换
- centos执行-查看,复制,删除-命令的脚本