JavaScript:getComputedStyle浏览器之间的返回值不一致

时间:2017-02-08 00:43:59

标签: javascript

我试图获得CSS left属性的值,如此... window.getComputedStyle(document.querySelector('.test'), ':after').getPropertyValue('left');

问题是,这会在Chrome中返回一个像素值,但在FireFox中会返回一个百分比。有没有办法让它强制它总是返回像素值?

JSFiddle:https://jsfiddle.net/r8mynvL4/2/

HTML:

<div class="test">This is a test.</div>

CSS:

.test {
  border: 1px solid black;
  position: relative;
}

.test:after {
  content: '*';
  bottom: -10%;
  left: 95%;
  position: absolute;
}

JS:

var leftValue = window.getComputedStyle(document.querySelector('.test'), ':after').getPropertyValue('left');

console.log(leftValue);

1 个答案:

答案 0 :(得分:2)

要直接回答这个问题,是的,请按照bugzilla report中最初描述的e.generalov尝试这种方法:

function getComputedStylePropertyValue(who, pseudo, propName) {
    var dv = who.ownerDocument.defaultView,
        cStyle = dv.getComputedStyle(who, pseudo),
        tmpNode = null, propVal;

    if (pseudo) {
        var css = cStyle.cssText;
        if (!css) { // it is an empty string. https://bugzilla.mozilla.org/show_bug.cgi?id=137687 
            var sty = [];
            for (var key in cStyle) {
                if (cStyle.hasOwnProperty(key)) {
                    sty.push(cStyle[key] + ':' + cStyle.getPropertyValue(cStyle[key]));
                }
            }
            css = sty.join(';');
        }
        tmpNode = document.createElement('dummy');
        tmpNode.style.cssText = css;
        if (pseudo === '::before' && who.firstChild) {
            who.insertBefore(tmpNode, who.firstChild);
        } else { // ::before in case of empty element or ::after
            who.appendChild(tmpNode);
        }
        cStyle = dv.getComputedStyle(tmpNode, null);
    }

    propVal = cStyle.getPropertyValue(propName);

    if (tmpNode) {
        tmpNode.parentNode.removeChild(tmpNode);
    }
    return propVal;
}

Here it is as a fiddle

哪种浏览器正确?

您可能会感到惊讶的是,实际上 Gecko(Firefox) 正确实现了规范。 (我说出现了,因为它的某些部分当然可能还有错误)。快速摘要为this part of the 'left' property definition

  

否则:如果指定为&#39;&lt; length&gt;&#39;,则相应的绝对长度;如果指定为&#39;&lt; percentage&gt;&#39;,则为指定值;否则,自动。

计算值的定义 - 左属性。 &#34;否则&#34;正在申请,因为职位:绝对声明。

那么,为什么Chrome不这样做呢?看起来相当清楚吧?好吧,如果您有兴趣了解该标准如何变得相对不一致,请继续阅读!

CSS的演变 - 向后兼容性与一致性的斗争

首先,像Chrome这样的新用户代理不需要为向后兼容而烦恼,并且基本上可以忽略CSS规范中较旧且更加模糊的部分。

对于Gecko和规范本身而言,它当然是另一回事。 CSS是无版本的 - 例如,您的网站没有声明它使用的CSS版本。相反,CSS模块在彼此之上有机地构建必须向后兼容。

与此同时,Chrome赞成一致性。它偶尔会偏离严格的规范定义,其理由是推动网络向前发展。典型的结果是规范得到更新以反映任何结果都很好。

但Firefox与自身不一致?当然这是一个错误?

This fiddle表明非伪元素确实返回px值。简而言之,这归功于CSS模块相互引用的方式。严格遵守这种引用方案,使得Firefox从W3C的角度来看是事实上的参考实现。

因此,例如,getComputedStyle的定义明确引用了CSS级别2:

  

此方法用于获取[CSS2] 中定义的计算样式

如果我们继续查看计算值的定义,因为它是defined in there,那么我们看到它曾经以像素定义:

  

百分比必须乘以参考值(每个属性定义哪个值)

同时,伪元素如:: before和:: after明确引用CSS3;他们使用left的{​​3}}的CSS3说明。

请记住,此规范是一个工作草案 - 浏览器不要求它遵循它(但Firefox正在这样做)。另一方面,Chrome推动了一致性线 - 即整个API始终只返回那些使用的值