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

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


当前回答

根据MDN:确定元素的尺寸

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

clientWidth和clienttheight返回“实际显示内容占用的空间大小,包括填充,但不包括边框、页边距或滚动条”

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

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

其他回答

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

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.getBoundingClientRect()。

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

{
    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将四舍五入到最近的整数。

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

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

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

值得注意的是,该方法返回的对象并不是真正的普通对象。它的属性是不可枚举的(例如,Object。钥匙不能开箱即用。)

更多信息请点击这里: 如何最好地将一个ClientRect / DomRect转换为一个普通对象

参考:

.offsetHeight: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight .offsetWidth: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth .getBoundingClientRect (): https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

下面是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 = 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 {

        }
    }
}

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

var divID = document.getElementById("divid");

var h = divID.style.pixelHeight;

你只需要为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>居中,并将其收缩到其内容的大小。