我如何检索HTML元素's实际宽度和高度?

假设我有一个<div>,我希望它位于浏览器显示(视口)的中央。为此,我需要计算<div>元素的宽度和高度。

我应该用什么?请包括浏览器兼容性信息。

1353165 次浏览

# 0: # 1

从jQuery 1.2.6开始,你可以使用核心CSS功能heightwidth中的一个(或者outerHeightouterWidth,视情况而定)。

var height = $("#myDiv").height();var width = $("#myDiv").width();
var docHeight = $(document).height();var docWidth = $(document).width();
你应该使用# 0# 1属性。注意它们属于元素,而不是.style
var width = document.getElementById('foo').offsetWidth;

函数# 0在执行CSS转换后以浮点数的形式返回元素的尺寸和位置。

> console.log(document.getElementById('foo').getBoundingClientRect())DOMRect {bottom: 177,height: 54.7,left: 278.5,​right: 909.5,top: 122.3,width: 631,x: 278.5,y: 122.3,}

元素。offsetWidth和元素。offsetHeight应该这样做,就像在之前的帖子中建议的那样。

但是,如果您只想集中内容,还有更好的方法。假设您使用严格的xhtml DOCTYPE。设置body标签的margin:0,auto属性和所需宽度(px)。内容与页面居中对齐。

你只需要为IE7和更老版本计算它(只有当你的内容没有固定大小时)。我建议使用HTML条件注释来限制攻击不支持CSS2的旧ie。对于所有其他浏览器使用这个:

<style type="text/css">html,body {display:table; height:100%;width:100%;margin:0;padding:0;}body {display:table-cell; vertical-align:middle;}div {display:table; margin:0 auto; background:red;}</style><body><div>test<br>test</div></body>

这是一个完美的解决方案。它以任何尺寸的<div>为中心,并将其收缩到内容的大小。

你也可以使用下面的代码:

var divID = document.getElementById("divid");
var h = divID.style.pixelHeight;

... 看起来CSS有助于把div放在中心…

<style>.monitor {position:fixed;/* ... absolute possible if on :root */top:0;bottom:0;right:0;left:0;visibility:hidden;}.wrapper {width:200px;/* this is size range */height:100px;position:absolute;left:50%;top:50%;visibility:hidden;}
.content {position:absolute;width: 100%;height:100%;left:-50%;top:-50%;visibility:visible;}
</style>
<div class="monitor"><div class="wrapper"><div class="content">
... so you hav div 200px*100px on center ...
</div></div></div>

如果offsetWidth返回0,你可以获取元素的样式宽度属性并搜索一个数字。100px -> 100

/ \ d * / .exec (MyElement.style.width)

看看第一条。

这个方法将返回一个包含widthheight和其他一些有用值的对象:

{width: 960,height: 71,top: 603,bottom: 674,left: 360,right: 1320}

例如:

var element = document.getElementById('foo');var positionInfo = element.getBoundingClientRect();var height = positionInfo.height;var width = positionInfo.width;

我相信这没有.offsetWidth.offsetHeight的问题,它们有时会返回0(如这里的评论中所讨论的那样)

另一个区别是getBoundingClientRect()可能返回小数像素,其中.offsetWidth.offsetHeight将四舍五入到最接近的整数。

IE8注意: getBoundingClientRect不返回IE8及以下的高度和宽度

如果你必须支持IE8,请使用.offsetWidth.offsetHeight:

var height = element.offsetHeight;var width = element.offsetWidth;

值得注意的是,该方法返回的对象实际上不是正常的对象。它的属性不是< em >可列举的< / em >(因此,例如,Object.keys不能开箱即用)。

更多信息在这里:# 0 < / p >

参考:

  • # 1: # 2
  • # 1: # 2
  • # 1: # 2

以防它对任何人都有用,我把一个文本框,按钮和div都用相同的css:

width:200px;height:20px;border:solid 1px #000;padding:2px;
<input id="t" type="text" /><input id="b" type="button" /><div   id="d"></div>

我尝试了它在chrome, firefox和ie-edge,我尝试了jquery和没有,我尝试了它与没有box-sizing:border-box。总是选择第一名

结果:

                                                               Firefox       Chrome        IE-Edgewith   w/o    with   w/o    with   w/o     box-sizing
$("#t").width()                                               194    200    194    200    194    200$("#b").width()                                               194    194    194    194    194    194$("#d").width()                                               194    200    194    200    194    200
$("#t").outerWidth()                                          200    206    200    206    200    206$("#b").outerWidth()                                          200    200    200    200    200    200$("#d").outerWidth()                                          200    206    200    206    200    206
$("#t").innerWidth()                                          198    204    198    204    198    204$("#b").innerWidth()                                          198    198    198    198    198    198$("#d").innerWidth()                                          198    204    198    204    198    204
$("#t").css('width')                                          200px  200px  200px  200px  200px  200px$("#b").css('width')                                          200px  200px  200px  200px  200px  200px$("#d").css('width')                                          200px  200px  200px  200px  200px  200px
$("#t").css('border-left-width')                              1px    1px    1px    1px    1px    1px$("#b").css('border-left-width')                              1px    1px    1px    1px    1px    1px$("#d").css('border-left-width')                              1px    1px    1px    1px    1px    1px
$("#t").css('padding-left')                                   2px    2px    2px    2px    2px    2px$("#b").css('padding-left')                                   2px    2px    2px    2px    2px    2px$("#d").css('padding-left')                                   2px    2px    2px    2px    2px    2px
document.getElementById("t").getBoundingClientRect().width    200    206    200    206    200    206document.getElementById("b").getBoundingClientRect().width    200    200    200    200    200    200document.getElementById("d").getBoundingClientRect().width    200    206    200    206    200    206
document.getElementById("t").offsetWidth                      200    206    200    206    200    206document.getElementById("b").offsetWidth                      200    200    200    200    200    200document.getElementById("d").offsetWidth                      200    206    200    206    200    206

根据MDN:确定元素的尺寸

offsetWidthoffsetHeight返回“一个元素占用的空间总量,包括可见内容的宽度、滚动条(如果有的话)、填充和边框”

clientWidthclientHeight返回“实际显示内容所占的空间,包括填充,但不包括边框,页边距或滚动条”

scrollWidthscrollHeight返回“内容的实际大小,不管它当前有多少可见”

因此,这取决于所测量的内容是否预计在当前可视区域之外。

修改元素的样式很容易,但读取值有点棘手。

JavaScript不能读取任何来自css(内部/外部)的元素样式属性(element .style),除非你在JavaScript中使用内置方法调用getComputedStyle。

getComputedStyle(元素(伪)

元素:读取其值的元素伪元素:如果需要,则为伪元素,例如::before。空字符串或无参数表示元素本身。

结果是一个具有样式属性的对象,如elem。样式,但现在是关于所有CSS类。

例如,这里的样式看不到页边距:

<head><style> body { color: red; margin: 5px } </style></head><body>
<script>let computedStyle = getComputedStyle(document.body);
// now we can read the margin and the color from it
alert( computedStyle.marginTop ); // 5pxalert( computedStyle.color ); // rgb(255, 0, 0)</script>
</body>

因此,修改javaScript代码以包含您希望获取其宽度/高度或其他属性的元素的getComputedStyle

window.onload = function() {
var test = document.getElementById("test");test.addEventListener("click", select);

function select(e) {var elementID = e.target.id;var element = document.getElementById(elementID);let computedStyle = getComputedStyle(element);var width = computedStyle.width;console.log(element);console.log(width);}
}

计算和解析值

CSS中有两个概念:

计算出的样式值是所有CSS规则和CSS之后的值继承被应用,作为CSS级联的结果。它看起来比如高度:1em或字体大小:125%

已解析的样式值是最终应用于元素的样式值。1em或125%这样的值是相对的。浏览器接受计算结果值并使所有单位固定和绝对,例如:高度:20px或字体大小:16px。用于几何属性解析值可以有一个浮点数,比如width:50.5px.

很久以前创建了getComputedStyle来获取计算值,但事实证明解析值要方便得多,因此标准发生了变化所以现在getComputedStyle实际上返回属性的解析值

请注意:

getComputedStyle需要完整的属性名

你应该总是询问你想要的确切属性,比如左,高,宽。否则正确的

.

. 例如,如果有属性paddingLeft/paddingTop,那么我们应该为getComputedStyle(elem).padding获取什么?什么,或也许是从已知填充中“生成”的值?没有标准规则。< / p >

还有其他不一致之处。例如,一些浏览器(Chrome)在下面的文档中显示10px,而其中一些(Firefox) -不显示:

<style>body {margin: 30px;height: 900px;}</style><script>let style = getComputedStyle(document.body);alert(style.margin); // empty string in Firefox</script>

更多信息https://javascript.info/styles-and-classes

下面是WKWebView的代码,它决定了特定Dom元素的高度(不适用于整个页面)

let html = "<body><span id=\"spanEl\" style=\"font-family: '\(taskFont.fontName)'; font-size: \(taskFont.pointSize - 4.0)pt; color: rgb(\(red), \(blue), \(green))\">\(textValue)</span></body>"webView.navigationDelegate = selfwebView.loadHTMLString(taskHTML, baseURL: nil)
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {webView.evaluateJavaScript("document.getElementById(\"spanEl\").getBoundingClientRect().height;") { [weak self] (response, error) inif let nValue = response as? NSNumber {
}}}

Flex

如果你想在<div>中显示屏幕中心的某种弹出消息,那么你不需要读取<div>的大小,但你可以使用flex

.box {width: 50px;height: 20px;background: red;}
.container {display: flex;justify-content: center;align-items: center;height: 100vh;width: 100vw;position: fixed; /* remove this in case there is no content under div (and remember to set body margins to 0)*/}
<div class="container"><div class="box">My div</div></div>

使用width参数如下:

   style=\{\{width: "80%",paddingLeft: 100,paddingRight: 200,paddingTop: 30,paddingBottom: 30,border: "3px solid lightGray",}}

我为此创建了一个具有高度灵活性的效用函数:

export type Size = {width: number, height: number};export enum GetSize_Method {/** Includes: content, padding. Excludes: border, margin, scroll-bar (if it has one), "position:absolute" descendants. */ClientSize = "ClientSize",/** Includes: content, padding, border, margin, scroll-bar (if it has one). Excludes: "position:absolute" descendants. */OffsetSize = "OffsetSize",/** Includes: content, padding, border, margin, scroll-bar (if it has one), "position:absolute" descendants. Excludes: none. */ScrollSize = "ScrollSize",/** Same as ScrollSize, except that it's calculated after the element's css transforms are applied. */BoundingClientRect = "BoundingClientRect",/** Lets you specify the exact list of components you want to include in the size calculation. */Custom = "Custom",}export type SizeComp = "content" | "padding" | "border" | "margin" | "scrollBar" | "posAbsDescendants";
export function GetSize(el: HTMLElement, method = GetSize_Method.ClientSize, custom_sizeComps?: SizeComp[]) {let size: Size;if (method == GetSize_Method.ClientSize) {size = {width: el.clientWidth, height: el.clientHeight};} else if (method == GetSize_Method.OffsetSize) {size = {width: el.offsetWidth, height: el.offsetHeight};} else if (method == GetSize_Method.ScrollSize) {size = {width: el.scrollWidth, height: el.scrollHeight};} else if (method == GetSize_Method.BoundingClientRect) {const rect = el.getBoundingClientRect();size = {width: rect.width, height: rect.height};} else if (method == GetSize_Method.Custom) {const style = window.getComputedStyle(el, null);const styleProp = (name: string)=>parseFloat(style.getPropertyValue(name));
const padding = {w: styleProp("padding-left") + styleProp("padding-right"), h: styleProp("padding-top") + styleProp("padding-bottom")};const base = {w: el.clientWidth - padding.w, h: el.clientHeight - padding.h};const border = {w: styleProp("border-left") + styleProp("border-right"), h: styleProp("border-top") + styleProp("border-bottom")};const margin = {w: styleProp("margin-left") + styleProp("margin-right"), h: styleProp("margin-top") + styleProp("margin-bottom")};const scrollBar = {w: (el.offsetWidth - el.clientWidth) - border.w - margin.w, h: (el.offsetHeight - el.clientHeight) - border.h - margin.h};const posAbsDescendants = {w: el.scrollWidth - el.offsetWidth, h: el.scrollHeight - el.offsetHeight};
const sc = (name: SizeComp, valIfEnabled: number)=>custom_sizeComps.includes(name) ? valIfEnabled : 0;size = {width: sc("content", base.w) + sc("padding", padding.w) + sc("border", border.w)+ sc("margin", margin.w) + sc("scrollBar", scrollBar.w) + sc("posAbsDescendants", posAbsDescendants.w),height: sc("content", base.h) + sc("padding", padding.h) + sc("border", border.h)+ sc("margin", margin.h) + sc("scrollBar", scrollBar.h) + sc("posAbsDescendants", posAbsDescendants.h),};}return size;}

用法:

const el = document.querySelector(".my-element");console.log("Size:", GetSize(el, "ClientSize"));console.log("Size:", GetSize(el, "Custom", ["content", "padding", "border"]));

这是唯一对我有效的方法:

element.clientWidth -parseFloat(window.getComputedStyle(element, null).getPropertyValue("padding-left")) -parseFloat(window.getComputedStyle(element, null).getPropertyValue("padding-right"))