假设我有一个<div>我希望在浏览器的显示(视口)中居中的。为此,我需要计算<div>元素的宽度和高度。
我应该使用什么?请包含有关浏览器兼容性的信息。
假设我有一个<div>我希望在浏览器的显示(视口)中居中的。为此,我需要计算<div>元素的宽度和高度。
我应该使用什么?请包含有关浏览器兼容性的信息。
您应该使用.offsetWidthand.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处的评论中所述).offsetHeight0
另一个区别是getBoundingClientRect()可能返回小数像素,其中.offsetWidth和.offsetHeight将四舍五入到最接近的整数。
IE8 注意:getBoundingClientRect不返回IE8及以下版本的高度和宽度。*
如果您必须支持 IE8,请使用.offsetWidthand .offsetHeight:
var height = element.offsetHeight;
var width = element.offsetWidth;
值得注意的是,该方法返回的 Object 并不是真正的普通对象。它的属性是不可枚举的(例如,Object.keys不能开箱即用。)
更多信息在这里: 如何最好地将 ClientRect / DomRect 转换为普通对象
参考:
注意:这个答案写于 2008 年。当时对大多数人来说最好的跨浏览器解决方案确实是使用 jQuery。我将答案留给后代,如果您使用的是 jQuery,这是一个很好的方法。如果您使用的是其他框架或纯 JavaScript,则可接受的答案可能是要走的路。
从 jQuery 1.2.6 开始,您可以使用核心CSS 函数之一, heightand width(或outerHeightand 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",
}}