假设我有一个<div>
我希望在浏览器的显示(视口)中居中的。为此,我需要计算<div>
元素的宽度和高度。
我应该使用什么?请包含有关浏览器兼容性的信息。
假设我有一个<div>
我希望在浏览器的显示(视口)中居中的。为此,我需要计算<div>
元素的宽度和高度。
我应该使用什么?请包含有关浏览器兼容性的信息。
您应该使用.offsetWidth
and.offsetHeight
属性。请注意,它们属于元素,而不是.style
.
var width = document.getElementById('foo').offsetWidth;
函数.getBoundingClientRect()
在执行 CSS 转换后将元素的尺寸和位置作为浮点数返回。
> console.log(document.getElementById('id').getBoundingClientRect())
DOMRect {
bottom: 177,
height: 54.7,
left: 278.5,
right: 909.5,
top: 122.3,
width: 631,
x: 278.5,
y: 122.3,
}
看看Element.getBoundingClientRect()
。
此方法将返回一个包含width
、height
和其他一些有用值的对象:
{
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
and .offsetHeight
:
var height = element.offsetHeight;
var width = element.offsetWidth;
值得注意的是,该方法返回的 Object 并不是真正的普通对象。它的属性是不可枚举的(例如,Object.keys
不能开箱即用。)
更多信息在这里: 如何最好地将 ClientRect / DomRect 转换为普通对象
参考:
注意:这个答案写于 2008 年。当时对大多数人来说最好的跨浏览器解决方案确实是使用 jQuery。我将答案留给后代,如果您使用的是 jQuery,这是一个很好的方法。如果您使用的是其他框架或纯 JavaScript,则可接受的答案可能是要走的路。
从 jQuery 1.2.6 开始,您可以使用核心CSS 函数之一, height
and width
(或outerHeight
and outerWidth
,视情况而定)。
var height = $("#myDiv").height();
var width = $("#myDiv").width();
var docHeight = $(document).height();
var docWidth = $(document).width();
以防万一它对任何人有用,我用相同的 css 放置了一个文本框、按钮和 div:
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
. 总是与<!DOCTYPE html>
结果:
Firefox Chrome IE-Edge
with 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 206
document.getElementById("b").getBoundingClientRect().width 200 200 200 200 200 200
document.getElementById("d").getBoundingClientRect().width 200 206 200 206 200 206
document.getElementById("t").offsetWidth 200 206 200 206 200 206
document.getElementById("b").offsetWidth 200 200 200 200 200 200
document.getElementById("d").offsetWidth 200 206 200 206 200 206
offsetWidth
并offsetHeight
返回“元素占用的总空间量,包括可见内容的宽度、滚动条(如果有)、填充和边框”
clientWidth
并clientHeight
返回“实际显示的内容占用了多少空间,包括填充但不包括边框、边距或滚动条”
scrollWidth
并scrollHeight
返回“内容的实际大小,无论当前可见多少”
所以这取决于测量的内容是否预计会超出当前的可视区域。
您只需要为 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>
以任何大小为中心,并将其收缩包装到其内容的大小。
修改元素样式很容易,但读取值有点棘手。
JavaScript 无法读取来自 css(internal/external) 的任何元素样式属性 (elem.style),除非您使用 javascript 中的内置方法调用 getComputedStyle。
getComputedStyle(元素[,伪])
元素:要为其读取值的元素。
伪:如果需要,一个伪元素,例如 ::before。空字符串或无参数表示元素本身。
结果是一个具有样式属性的对象,例如 elem.style,但现在涉及所有 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 ); // 5px
alert( 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 级联的结果。它可能看起来像 height:1em 或 font-size:125%。
已解决的样式值是最终应用于元素的样式值。像 1em 或 125% 这样的值是相对的。浏览器采用计算值并使所有单位固定和绝对,例如:height:20px 或 font-size:16px。对于几何属性,解析值可能有一个浮点数,例如 width:50.5px。
很久以前 getComputedStyle 被创建用于获取计算值,但结果证明解析值更方便,并且标准改变了。
所以现在 getComputedStyle 实际上返回了属性的解析值。
请注意:
getComputedStyle 需要完整的属性名称
您应该始终询问您想要的确切属性,例如 paddingLeft 或高度或宽度。否则不能保证正确的结果。
例如,如果有属性 paddingLeft/paddingTop,那么我们应该为 getComputedStyle(elem).padding 得到什么?什么都没有,或者可能是已知填充的“生成”值?这里没有标准规则。
还有其他不一致的地方。例如,一些浏览器 (Chrome) 在下面的文档中显示 10px,而其中一些 (Firefox) 则不显示:
<style>
body {
margin: 30px;
height: 900px;
}
</style>
<script>
let style = getComputedStyle(document.body);
alert(style.margin); // empty string in Firefox
</script>
element.offsetWidth 和 element.offsetHeight 应该按照上一篇文章中的建议进行。
但是,如果您只想使内容居中,则有更好的方法。假设您使用 xhtml 严格的 DOCTYPE。将 margin:0,auto 属性和所需宽度(以 px 为单位)设置为 body 标签。内容与页面中心对齐。
您也可以使用以下代码:
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>
如果您想<div>
在屏幕中心的某种弹出消息中显示 - 那么您不需要阅读 size of<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>
我为此创建了一个实用函数,具有很高的灵活性:
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"))
如果 offsetWidth 返回 0,则可以获取元素的样式宽度属性并在其中搜索数字。“100 像素”-> 100
/\d*/.exec(MyElement.style.width)
这是确定特定 Dom 元素高度的WKWebView的代码(不适用于整个页面)
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 = self
webView.loadHTMLString(taskHTML, baseURL: nil)
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.getElementById(\"spanEl\").getBoundingClientRect().height;") { [weak self] (response, error) in
if let nValue = response as? NSNumber {
}
}
}
使用宽度参数如下:
style={{
width: "80%",
paddingLeft: 100,
paddingRight: 200,
paddingTop: 30,
paddingBottom: 30,
border: "3px solid lightGray",
}}