2017-02-08 3 views
3

間getComputedStyle一貫性のない戻り値... window.getComputedStyle(document.querySelector('.test'), ':after').getPropertyValue('left');JavaScriptを:私はそうのようなCSS左属性の値を取得しようとしていますブラウザ

問題は、これが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); 
+2

ああ、既にある:https://bugzilla.mozilla.org/show_bug.cgi?id=925694#comment_tag_7 – Kaiido

+0

'getComputedStyleは、計算された値を返すべきで、直列化されたpx'を返さなければならない - それはすべての属性に当てはまるわけではない - https://developer.mozilla.org/en/docs/Web/API/Window/getComputedStyle#Notes –

+0

を参照してください。@Kaiido - このバグは 'width'と' height'に関するものです - 'left'とは関係ありません –

答えて

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である:それ以外の場合

:「<長>」、対応する絶対的な長さとして指定した場合、 '<パーセント>'と指定した場合、指定された値。そうでなければ、自動。

計算値の定義 - leftプロパティ。 "それ以外の場合"は位置のために適用されます:絶対的な宣言。

だから、なぜChromeはそれをしませんか?それはかなり明白ですね。さて、もしこの標準がどのように矛盾していたのかを知りたいのであれば、読んでください!

CSSの進化 - 一貫

対後方互換性の戦いまず、クロムなどの新しいユーザーエージェントが後方互換性をあまり気にする必要はありませんし、基本的にCSSの古い、よりあいまいな部分を無視することができます仕様。

もちろん、Geckoと仕様自体は別の話です。 CSSはで、バージョンはです。あなたのウェブサイトでは、たとえば使用しているCSSのバージョンを宣言していません。その代わりに、CSSモジュールは有機的にの上に構築され、と下位互換性がなければなりません。

一方、Chromeでは一貫性が優先されます。時折、仕様の厳密な定義からかなり離れていて、ウェブを前方に押すという推論があります。典型的な結果は、仕様が良くなったものを反映するように更新されていることです。

しかし、Firefoxはそれ自体と矛盾していますか?確かにそれはバグですか?

This fiddleは、非擬似要素が実際にpx値を返すことを示しています。要するに、これは、CSSモジュールが相互に参照する方法に起因します。これは、W3Cの観点から、Firefoxを事実上のリファレンス実装にする、この参照スキームへの厳密な遵守です。この方法は、それが[CSS2]で定義されているように計算スタイルを取得するために使用され

だから、例えば、getComputedStyleの定義は明示的にCSSレベル2を参照しています。

我々は、それは我々がそれを一度ピクセル単位で定義されていたことがわかり、その後defined in thereあるとして計算値の定義を見てみることを進む場合:

割合が基準値を掛けなければなりません

(それぞれのプロパティはどの値であるかを定義します)

一方、:: beforeや:: afterのような疑似要素は、CSS3を明示的に参照します。彼らはleftのCSS3の記述を使用します。now defines it differentlyです。

この仕様書は作業用の草案であることに注意してください。ブラウザはそれに従う必要はありませんが(Firefoxはそうしています)。一方、Chromeは一貫性ラインを押しています。つまり、API全体では常にの値がの値しか返されません。

+0

これは、Firefoxでピクセル値を取得するためにすごくうまく機能しますが、私はまだSafariでパーセンテージを取得しています...ブラウザに関係なく常にピクセルを返すように、提供する関数を変更する方法はありますか? –

+0

@m-use Safariで非擬似要素が%を返すように聞こえます。それが当てはまる場合は、%単位を自分で解決する以外には不運になります。例えば。 'cStyle.contains( '%')'が数値を解析し、それを基準値で掛けます。参照値を求めることは難しい:それは軸に依存する(すなわち、margin-top:50%はYにあり、margin-left:50%はXにある)、プロパティは相対的なもの-sizeは "this"に相対的ですが、大半は "親"の内側の幅/内側の高さに関連しています)。 「親」は要素の配置方法にも依存します。 –

+0

(たとえば、 'position:fixed;' top:50%はビューポートの50%ですが、最も近い変換された祖先の50%になることもあります) –

関連する問題