【问题标题】:Cross-browser (IE8-) getComputedStyle with Javascript?使用 Javascript 的跨浏览器(IE8-)getComputedStyle?
【发布时间】:2013-03-21 22:22:49
【问题描述】:

由于IE8不支持getComputedStyle,我们只能使用currentStyle。但是,它不会返回某些属性的真正“计算”值。

例如:

<style type="text/css">
#div {/* no properties are defined here */}
</style>
<div id="div">div</div>
// returns "medium" instead of 0px
document.getElementById('div').currentStyle.borderLeftWidth

// returns "auto" instead of 0px
document.getElementById('div').currentStyle.marginLeft

// returns "undefined" instead of 1
document.getElementById('div').currentStyle.opacity

是否有人在不使用 jQuery 或其他 Javascript 库的情况下为所有属性提供跨浏览器解决方案?

【问题讨论】:

  • IE currentStyle 对象显示这些属性的浏览器默认值。也许您可以使用 CSS 重置来规范所有浏览器的默认设置。
  • @Pointy 我正在寻找 Javascript 解决方案,因为我正在编写一个小型库,我不希望它改变用户的样式。
  • 这个link 可能对你有帮助。
  • @Mr_Green 谢谢,但没有帮助。我以前看过那个页面。代码无法将mediumauto等值解析为px

标签: javascript internet-explorer cross-browser styles


【解决方案1】:

这是一个获取计算样式的跨浏览器函数...

getStyle = function (el, prop) {
    if (typeof getComputedStyle !== 'undefined') {
        return getComputedStyle(el, null).getPropertyValue(prop);
    } else {
        return el.currentStyle[prop];
    }
}

您可以将其作为实用程序存储在对象中,或者仅按提供的方式使用它。这是一个示例演示!

// Create paragraph element and append some text to it
var p = document.createElement('p');
p.appendChild(document.createTextNode('something for fun'));

// Append element to the body
document.getElementsByTagName('body')[0].appendChild(p);

// Set hex color to this element
p.style.color = '#999';

// alert element's color using getStyle function
alert(getStyle(p, 'color'));

查看此演示以查看实际效果:

getStyle = function(el, prop) {
  if (getComputedStyle !== 'undefined') {
    return getComputedStyle(el, null).getPropertyValue(prop);
  } else {
    return el.currentStyle[prop];
  }
}

// Create paragraph element and append some text to it
var p = document.createElement('p');
p.appendChild(document.createTextNode('something for fun'));

// Append element to the body
document.getElementsByTagName('body')[0].appendChild(p);

// Set hex color to this element
p.style.color = '#999';

// alert element's color using getStyle function
console.log(getStyle(p, 'color'));
p {
  color: red;
}

【讨论】:

  • 这对于像 backgroundColor 这样的 prop 将失败,因为 getPropertyValue 需要 CSS 属性名称,但 currentStyle 将其作为驼峰式版本。单行替换:return (typeof getComputedStyle !== 'undefined' ? getComputedStyle(el, null) : el.currentStyle)[prop];
  • 这不能回答问题。问题要求“所有属性”的跨浏览器解决方案,即使是问题中提到的“currentStyle”不返回实际计算值的那些。
【解决方案2】:

您不想使用 jquery,但没有什么可以阻止您查看代码并查看它们是如何处理的 :-)

在 jquery 代码中,有一个关于 this comment 的参考,这似乎很重要(也请阅读整篇文章)。 这是应该处理您的问题的 jquery 代码:

else if ( document.documentElement.currentStyle ) {
    curCSS = function( elem, name ) {
        var left, rsLeft,
            ret = elem.currentStyle && elem.currentStyle[ name ],
        style = elem.style;

    // Avoid setting ret to empty string here
    // so we don't default to auto
    if ( ret == null && style && style[ name ] ) {
        ret = style[ name ];
    }

    // From the awesome hack by Dean Edwards
    // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291

    // If we're not dealing with a regular pixel number
    // but a number that has a weird ending, we need to convert it to pixels
    // but not position css attributes, as those are proportional to the parent element instead
    // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
    if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {

        // Remember the original values
        left = style.left;
        rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;

        // Put in the new values to get a computed value out
        if ( rsLeft ) {
            elem.runtimeStyle.left = elem.currentStyle.left;
        }
        style.left = name === "fontSize" ? "1em" : ret;
        ret = style.pixelLeft + "px";

        // Revert the changed values
        style.left = left;
        if ( rsLeft ) {
            elem.runtimeStyle.left = rsLeft;
        }
    }

    return ret === "" ? "auto" : ret;
};
}

【讨论】:

  • 如果其他人想知道,rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" );。完整的独立源代码可以在这里找到:stackoverflow.com/questions/17884653
【解决方案3】:

而不是:

getComputedStyle !== 'undefined'

应该是:

typeof getComputedStyle !== 'undefined'

否则它永远不会起作用。

【讨论】:

    【解决方案4】:

    这不适用于所有样式,但适用于尺寸(这是我需要的)。

    不要试图猜测应用了哪些样式,只需使用类似盒子的元素的四个边中的每一个边的像素位置来计算尺寸。这也适用于 IE 5 和 FF 3。

    height = elem.getBoundingClientRect().bottom - elem.getBoundingClientRect().top;
    width = elem.getBoundingClientRect().right - elem.getBoundingClientRect().left;
    

    另请参阅:getBoundingClientRect is awesome

    如果这仍然不适合您,请查看 this fiddle 我为计算盒子的内部宽度而整理的。它使用以下内容作为 getComputedStyle 的垫片:

    /**
     * getComputedStyle function for IE8
     * borrowed from:
     * http://missouristate.info/scripts/2013/common.js
     */
    "getComputedStyle" in window || function() {
      function c(a, b, g, e) {
        var h = b[g];
        b = parseFloat(h);
        h = h.split(/\d/)[0];
        e = null !== e ? e : /%|em/.test(h) && a.parentElement ? c(a.parentElement, a.parentElement.currentStyle, "fontSize", null) : 16;
        a = "fontSize" == g ? e : /width/i.test(g) ? a.clientWidth : a.clientHeight;
        return "em" == h ? b * e : "in" == h ? 96 * b : "pt" == h ? 96 * b / 72 : "%" == h ? b / 100 * a : b;
      }
      function a(a, c) {
        var b = "border" == c ? "Width" : "", e = c + "Top" + b, h = c + "Right" + b, l = c + "Bottom" + b, b = c + "Left" + b;
        a[c] = (a[e] == a[h] == a[l] == a[b] ? [a[e]] : a[e] == a[l] && a[b] == a[h] ? [a[e], a[h]] : a[b] == a[h] ? [a[e], a[h], a[l]] : [a[e], a[h], a[l], a[b]]).join(" ");
      }
      function b(b) {
        var d, g = b.currentStyle, e = c(b, g, "fontSize", null);
        for (d in g) {
          /width|height|margin.|padding.|border.+W/.test(d) && "auto" !== this[d] ? this[d] = c(b, g, d, e) + "px" : "styleFloat" === d ? this["float"] = g[d] : this[d] = g[d];
        }
        a(this, "margin");
        a(this, "padding");
        a(this, "border");
        this.fontSize = e + "px";
        return this;
      }
      b.prototype = {};
      window.getComputedStyle = function(a) {
        return new b(a);
      };
    }();
    

    【讨论】:

      【解决方案5】:

      这对于编辑来说太大了,所以它是一个答案,但它没有提供手头问题的完整答案。


      Gabriel's answer 失败,并显示 "backgroundColor""background-color" 之类的属性,具体取决于浏览器版本,因为 .getPropertyValue 需要 CSS 属性名称,el.currentStyle[prop] 需要驼峰式版本。

      这是一个固定版本,它总是需要驼峰版本:

      function getStyle(el, prop) {
          return (typeof getComputedStyle !== 'undefined' ?
              getComputedStyle(el, null) :
              el.currentStyle
          )[prop]; // avoid getPropertyValue altogether
      }
      

      【讨论】:

      • 这并没有回答这个问题。您只是修复了另一个也没有回答问题的答案。
      • @blissfool 它确实回答了我和许多其他人似乎正在寻找的关于 getComputedStyle 的跨浏览器等效项的部分(基于赞成票) .虽然您有权不喜欢我的回答,但它对于编辑来说太大了,它可以帮助将来遇到这个问题的人,所以我认为它不值得一票。
      • 从技术上讲,问题不是询问“getComputedStyle 的跨浏览器等效项”。嗯,确实是这样,但它被询问的方式是它也应该一直返回正确的值。这个问题最后不是很清楚,但那是上下文。他们已经知道需要使用 getComputedStyle 或 currentStyle。
      • 我同意这可能对遇到这个问题并打算改变我的投票但由于时间过长而被锁定的人有所帮助。如果您想进行任何细微的修改,我会改变我的投票。
      • @blissfool 我添加了免责声明来解释为什么存在这个答案。如果您仍然需要,这应该可以让您调整投票。
      猜你喜欢
      • 1970-01-01
      • 2014-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 2013-02-02
      • 2015-05-16
      • 2011-08-02
      • 2011-12-18
      相关资源
      最近更新 更多