foreword(前言)

首先,非常抱歉太长时间没有更新专栏了,这两三个月一直在处理人生两大重要的事。。。闲话少说,进入正题。

最近项目中需要获取 dom 元素的尺寸,所以借此对比分析一下 js 所有获取尺寸的方法,以及相关的 dom 定位方式。

JS 尺寸、定位都有哪些获取方式呢

JS 尺寸获取方法:

  • clientWidth & clientHeight
  • offsetWidth & offsetHeight
  • scrollWidth & scrollHeight
  • getComputedStyle
  • getBoundingClientRect

clientWidth & clientHeight

The Element.clientWidth property is zero for inline elements and elements with no CSS; otherwise, it's the inner width of an element in pixels. It includes padding but excludes borders, margins, and vertical scrollbars (if present).

clientWidth 包括 content、padding 两个部分,而不包括 border、margin,以及滚动条的宽度。

offsetWidth & offsetHeight

Typically, offsetWidth is a measurement in pixels of the element's CSS width, including any borders, padding, and vertical scrollbars (if rendered). It does not include the width of pseudo-elements such as ::before or ::after.

offsetWidth 包括 content、padding、滚动条、border。

scrollWidth & scrollHeight

The scrollWidth value is equal to the minimum width the element would require in order to fit all the content in the viewport without using a horizontal scrollbar. The width is measured in the same way as clientWidth: it includes the element's padding, but not its border, margin or vertical scrollbar (if present). It can also include the width of pseudo-elements such as ::before or ::after. If the element's content can fit without a need for horizontal scrollbar, its scrollWidth is equal to clientWidth.

scrollWidth 在没有横向滚动条的时候,大小跟 clientWidth 一样;而如果有横向滚动条,则是可视区域 + 隐藏区域 + padding。

以下是一段测试代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#box {width: 100px;height: 100px;padding: 10px;background: red;overflow: auto;}</style>
</head><body><div id="box">hkjhjkhhkjhkjhjkhjkhjkhhkhkjhjkhjkhkjhkjhkjhjkhjkjkjkljljklhkjhjkhjkhkjhjkhhkjhjkhhkjhjkhhkjhjkhhkjhjkhhkjhjkhhkjhjkhhkjhjkhhkjhjkh</div><script>var box = document.getElementById('box')// clientconsole.log('clientWidth:', box.clientWidth)console.log('clientHeight:', box.clientHeight)// offsetconsole.log('offsetWidth:', box.offsetWidth)console.log('offsetHeight:', box.offsetHeight)// srollconsole.log('scrollWidth:', box.scrollWidth)console.log('scrollHeight:', box.scrollHeight)</script>
</body></html>

注:clientXXX & offsetXXX & scrollXXX 获取的数据均为 round 四舍五入取整过,如果想要精确的数值,则可以通过 element.getBoundingClientRect() 进行获取。

getComputedStyle

The Window.getComputedStyle() method returns an object containing the values of all CSS properties of an element, after applying active stylesheets and resolving any basic computation those values may contain. Individual CSS property values are accessed through APIs provided by the object, or by indexing with CSS property names.

Window.getComputedStyle 方法返回一个对象,可以通过属性名或者它提供的 api 方法获取某个 css 属性的值。

语法:

var style = window.getComputedStyle(element [, pseudoElt]);

参数:

  • element: 我们想要获取样式的 dom 元素对象;
  • pseudoElt: 伪元素选择器;

大致意思就是,如果只传第一个参数,则获取的是第一个参数 element 的样式集合对象,而如果传了两个参数,则是获取 element 中匹配 pseudoElt 伪元素选择器的伪元素的样式集合对象。

注,以下情况下,浏览器会抛 TypeError 的异常:

  • element 不是一个 element 类型的 dom 元素对象;
  • pseudoElt 不是一个有效的伪元素选择器,这里说的有效性是指语法有效性,比如:“::unsupported” 这个选择器虽然不存在,但是它语法是有效的,所以不会被抛异常;

以下是一段测试代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#box {width: 100px;height: 100px;padding: 10px;background: red;overflow: auto;}#box::before {content: '';width: 55px;height: 55px;line-height: 55px;display: block;background: yellow;}#box::after {content: '';width: 55px;height: 55px;display: block;background: green;}</style>
</head><body><div id="box"></div><script>var box = document.getElementById('box')var computedStyleObj = window.getComputedStyle(box, '::before')console.log('computedStyleObj-lineHeight:', computedStyleObj.lineHeight) // 55pxconsole.log('computedStyleObj-lineHeight:', computedStyleObj.getPropertyValue('line-height')) // 55px</script>
</body></html>

window.getComputedStyle 返回的对象其实和 element.style 返回的对象属于同一种类型—— CSSStyleDeclaration,但是两者还是有区别的:

  • window.getComputedStyle 返回的对象是只读的,并不能设置样式;
  • element.style 返回的对象可读写,可以直接通过 element.style[Css Attribute Name] 的形式在行内样式上设置样式;

在许多在线的演示代码中,getComputedStyle 是通过 document.defaultView 对象来调用的。大部分情况下,这是不需要的,因为可以直接通过 window 对象调用。但有一种情况,你必需要使用 defaultView, 那是在 firefox3.6 上访问子框架内的样式 。

注:

  • 返回的 CSSStyleDeclaration 对象将包含所有受支持的 CSS 属性长名称的活动值,如:border-bottom-width;
  • 获取属性值有两种方法,api 或者索引,比如:window.getComputedStyle(element).getPropertyValue('border-bottom-width')、window.getComputedStyle(element).borderBottomWidth、window.getComputedStyle(element)['border-bottom-width']、window.getComputedStyle(element)['borderBottomWidth'];
  • getComputedStyle 的返回值是 resolved values, 通常跟 CSS2.1 中的 computed values 是相同的值。 但对于一些旧的属性,比如 width, height, padding 它们的值又为 used values。最初, CSS2.0 定义的计算值 Computed values 就是属性的最终值。 但是 CSS2.1 重新定义了 computed values 为布局前的值, used values 布局后的值。 布局前与布局后的区别是, width 或者 height 的百分比可以代表元素的宽度,在布局后会被像素值替换。

大致意思就是返回的值是计算过的值,比如:某些百分比的值会被计算,然后转换为 px 的值;

  • 在某些情况下,通过浏览器会特意返回不准确的值。 特别是在避免 CSS 浏览历史泄露的安全问题, 比如,浏览者看过某个网站,它的链接通常会变成蓝色带下划线的链接,通过判断链接的颜色(getComputedSytle(node, null).color) 是否为蓝色,就会泄露用户的浏览历史,所以浏览器会特意返回不准确的值,保护用户隐私。可以了解更多关于 css 安全的链接http://blog.mozilla.com/security/2010/03/31/plugging-the-css-history-leak/ 和http://hacks.mozilla.org/2010/03/privacy-related-changes-coming-to-css-vistited/
  • 返回的某些属性值是带有 px 的字符串,而不是简单的数值。

getBoundingClientRect

The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport. The element's size is equal to its width/height + padding + border-width in the case that the standard box model is being used, or width/height only if box-sizing: border-box has been set on it.

element.getBoundingClientRect() 返回的一个对象,这个对象包含了 element 的尺寸(标准盒子模型下的尺寸)和相对于窗口的定位。

以下为测试代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>div {width: 400px;height: 200px;padding: 20px;margin: 50px auto;background: purple;}</style>
</head><body><div></div><script>let elem = document.querySelector('div');function getInfo() {let elem = document.querySelector('div');let rect = elem.getBoundingClientRect();for (var key in rect) {if (typeof rect[key] !== 'function') {let para = document.createElement('p');para.textContent = `${ key } : ${ rect[key] }`;console.log(para);}}console.log('n')}window.onscroll = getInfo</script>
</body></html>

浏览器兼容性

详见以下文章末尾:

  • clientWidth & clientHeight:https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth
  • offsetWidth & offsetHeight:https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth
  • scrollWidth & scrollHeight:https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth
  • getComputedStyle:https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
  • getBoundingClientRect:https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

参考文章

  • clientWidth & clientHeight:https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth
  • offsetWidth & offsetHeight:https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth
  • scrollWidth & scrollHeight:https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth
  • getComputedStyle:https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
  • getBoundingClientRect:https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

last(最后)
非常感谢您能阅读完这篇文章,您的阅读是我不断前进的动力。
对于上面所述,有什么新的观点或发现有什么错误,希望您能指出。
最后,附上个人常逛的社交平台:
知乎:https://www.zhihu.com/people/bi-an-yao-91/activities
csdn:https://blog.csdn.net/YaoDeBiAn
github: https://github.com/yaodebian
个人目前能力有限,并没有自主构建一个社区的能力,如有任何问题或想法与我沟通,请通过上述某个平台联系我,谢谢!!!

js如何获取div下面的input_原生 js 如何获取宽高相关推荐

  1. 如何更改html广告,js 动态改变广告代码DIV的位置_原生JS通过innerHTML改变div位置...

    在实际的广告应用中时不时会出现这个需求,就是我投放的广告位距离用户经常点击的翻页太远了,网站主不愿意为了这个需求去把整站的内容生成一遍,那会耗费很长时间,而且不确定有没有错误,这个时候就需要广告代码中 ...

  2. JS结合PHP瀑布流,JavaScript_原生JS实现响应式瀑布流布局,原生JS实现的瀑布流布局,代 - phpStudy...

    原生JS实现响应式瀑布流布局 原生JS实现的瀑布流布局,代码及demo代码地址:https://github.com/leozdgao/responsive_waterfall Demo:http:/ ...

  3. js检测鼠标是否在操作_原生JS趣味demo:炫酷头像鼠标追随效果的实现

    我们常在一些网页中 可以看到鼠标追随效果 一个简单的图片.动画 甚至一小段文字 都可以作为鼠标跟随的载体 之前咱们的直播课中 老师也讲过相关的canvas追随粒子特效 今天 就让我们一起来用原生js ...

  4. 原生js清空上一个元素内容_原生js系列 删除元素

    // 删除id var idObject = document.getElementById('sidebar'); if (idObject != null) idObject.parentNode ...

  5. 原生js清空上一个元素内容_原生JS实现动态添加新元素、删除元素方法

    1. 添加新元素 动态添加新元素 Coffee Tea Coffee Tea var child = document.getElementsByClassName("child" ...

  6. android获取屏幕像素密度DPI、density、屏幕宽高

    获取手机屏幕像素密度 dpi DisplayMetrics metrics = new DisplayMetrics(); getActivity().getWindowManager().getDe ...

  7. js获取ul下面的li

    js 获取元素下面所有的li var div=document.getElementById("div"); var items=div.getElementsByTagName( ...

  8. ie下的placeholder原生js实现方法

    2019独角兽企业重金招聘Python工程师标准>>> css代码 *{margin: 0;padding: 0;}body{*text-align: center;}/*登陆表单* ...

  9. js获取classname值_用原生JS获取CLASS对象(很简单实用)

    听说是最常用....我是看了dom编程艺术想到的. 无标题文档 .ca{background-color:red; padding:20px;} .js{ border:1px solid #00F; ...

最新文章

  1. Springcloud中的region和zone的使用
  2. VSCode配置Python开发环境
  3. 从头开发一个 RPC 是种怎样的体验?
  4. vue脚手架实现选项卡_从零一步步实现一个前端脚手架
  5. java在线答疑系统_网上学习和答疑系统系统
  6. 电阻电容封装用错该怎么办
  7. AI机器人AI源码营销机器人电销机器人智能电话机器人拨号机器人语音机器人空号识别FreeSWITCH呼叫中心中间ipbxIPBX科大识别阿里识别语音识别语音翻译
  8. 湘潭十八中2021年高考成绩查询,2021年 湖南省湘潭市高中学校排名top10
  9. 哪几种MM最受男孩喜欢?(组图)
  10. 工程师为什么不转销售
  11. linux pppd ip up 脚本,pppd拨号脚本配置
  12. C语言循环语句——while、for、do while
  13. ftp工具绿色版,好用的ftp工具绿色版下载教程
  14. Python绘制三维立体图详解与绘图填充
  15. FS100N03替代NCE3080K新洁能30V 80A MOS场效应管
  16. 面试专题:苹果树(Qtrade)二面三面
  17. 雨阳打字通 v1.0 发布
  18. NR 物理层 卷积 狄拉克函数八讲1-狄拉克函数定义Delta Function
  19. unity3d-多人坦克对战
  20. I/O error reading PNG header! java截取png图片时遇到的问题

热门文章

  1. 关于java设计模式笔记
  2. c语言if-else的效率比较
  3. Java中Image类与ImageIcon类的区别
  4. 树莓派中找不到/dev/video0的解决方案及RaspberryCam的使用
  5. Yii2 解决2006 MySQL server has gone away问题
  6. MySQL_解决ERROR 2006 (HY000) at line XX MySQL server has gone away问题
  7. python 异常处理 try except
  8. 如何通过终端快速删除文件和目录(bash shell)[关闭]
  9. 如何正确地从IntelliJ构建jar?
  10. 从命令行列出所有环境变量?