【问题标题】:Get the height of an element minus padding, margin, border widths获取元素的高度减去填充、边距、边框宽度
【发布时间】:2014-08-08 06:23:36
【问题描述】:

有谁知道在没有内联高度声明的情况下是否可以获得元素的高度(减去垂直填充、边框和边距)?我需要支持IE8及以上。

el.style.height 不起作用,因为样式是在外部样式表中设置的。

el.offsetHeightel.clientHeight 不起作用,因为它们不仅仅包含元素的高度。而且我不能只减去元素的填充等,因为这些值也是在 CSS 样式表中设置的,而不是内联的(所以 el.style.paddingTop 不起作用)。

同样不能window.getComputedStyle(el),因为IE8不支持这个。

jQuery 有 height() 方法,它提供了这个,但是我在这个项目中没有使用 jQuery,另外我只是想知道如何在纯 JavaScript 中做到这一点。

有人有什么想法吗?非常感谢。

【问题讨论】:

  • 是的,但正如我提到的,jQuery 以某种方式通过 .height() 实现了这一点,所以这一定是可能的。
  • 它可能使用getComputedStyle,对于旧版IE,可能使用currentStyle
  • 是的,jQuery 的height()innerHeight() 在内部都使用css(),而css() 在内部使用getComputedStylecurrentStyle
  • get element inner height 的可能重复项
  • @adeneo 我不知道 currentStyle。如果我发现一些有用的东西,我会尝试 2 的一些组合并回发。谢谢!

标签: javascript css


【解决方案1】:

下面是适用于box-sizing 两种情况的解决方案:content-boxborder-box

var computedStyle = getComputedStyle(element);

elementHeight = element.clientHeight;  // height with padding
elementWidth = element.clientWidth;   // width with padding

elementHeight -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom);
elementWidth -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);

适用于 IE9+

你可以使用特征检测

if (!getComputedStyle) { alert('Not supported'); } 

如果元素的 displayinline,这将不起作用。使用inline-block 或使用getBoundingClientRect

【讨论】:

    【解决方案2】:

    改进了 Dan 的代码以处理内联元素(使用 offset* 而不是 client*):

    var cs = getComputedStyle(element);
    
    var paddingX = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);
    var paddingY = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom);
    
    var borderX = parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth);
    var borderY = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth);
    
    // Element width and height minus padding and border
    elementWidth = element.offsetWidth - paddingX - borderX;
    elementHeight = element.offsetHeight - paddingY - borderY;
    

    【讨论】:

    【解决方案3】:

    element.getComputedStyle 会根据box-sizing 的值返回高度。如果元素使用box-sizing: content-box;,您可以使用getComputedStyle 计算没有填充或边框的高度:

    var style = window.getComputedStyle(document.getElementById("Example"), null);
    style.getPropertyValue("height");
    

    以上版本可以在现代浏览器中使用。请检查 IE 浏览器的 currentStyle。

    跨浏览器:

    try {
     el = window.getComputedStyle(document.getElementById('example'), null)
         .getPropertyValue('height');
    } catch(e) {
     el = document.getElementById('example').currentStyle.height;
    } 
    

    source

    【讨论】:

    • getElementById 只能有一个参数.. 这个人是什么人? :)
    • 这种情况下也不需要使用try...catch,我们可以使用in操作符来检查成员是否存在,比如if('getComputedStyle' in window) ... 或者使用typeof比如@ 987654333@
    • 我要补充一点,如果元素的高度是自动的,.currentStyle.height 只会返回'auto',如果它的高度是百分比,它只会返回那个百分比,而不是以像素为单位计算的高度。所以在这种情况下,如果你仍然需要知道元素的高度,你可以取它的.offsetHeight,然后使用.currentStyle 来获取任何垂直填充或边框值,然后从 offsetHeight 值中减去它们给你元素的高度。虽然如果填充或边框也设置为百分比,这将不起作用。
    • 如果您使用box-sizing: border-box,这是最常用的,这将不起作用。
    • 这包含填充,至少当我尝试在 SVG 上使用它时
    【解决方案4】:

    把丹的答案变成了一个函数

    export const innerDimensions = (node) => {
      var computedStyle = getComputedStyle(node)
    
      let width = node.clientWidth // width with padding
      let height = node.clientHeight // height with padding
    
      height -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)
      width -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight)
      return { height, width }
    }
    

    【讨论】:

      【解决方案5】:

      IE8 中尝试 element.currentStyle。但请记住,borderRightWidth (borderLeftWidth) 返回的不是像素,而是“薄”、“中”、“厚”。

      【讨论】: