web-dev-qa-db-ja.com

JavaScriptでCSSが生成したコンテンツにアクセスする方法

CSSのcounterおよびcontentプロパティを使用して、ヘッダーと図の番号付けを生成します。

img.figure:after {
  counter-increment: figure;
  content: "Fig. " counter(section) "." counter(figure);
}

これ(適切なブラウザであると想定)は、画像に続いて「図1.1」、「図1.2」などのナイスラベルを付けます。

質問: Javascriptからこれにアクセスするにはどうすればよいですか?アクセスしたいという点で2つの質問がありますどちらか特定のカウンターの現在の値(特定のDOMノード)または CSSで生成されたコンテンツの値(特定のDOMノードで)または、明らかに、両方の情報。

背景:リンクに追加したいのですが、次のように適切な番号を図に参照します。

<a href="#fig1">see here</h>
------------------------^ " (Fig 1.1)" inserted via JS

私が見る限り、それはこの問題に要約されます:I couldcontentまたはcounter-incrementgetComputedStyle経由でアクセスします。

var fig_content = window.getComputedStyle(
                    document.getElementById('fig-a'),
                    ':after').content;

ただし、これはlive値ではなく、スタイルシートで宣言されている値です。 realライブ値にアクセスするためのインターフェイスが見つかりません。カウンターの場合、クエリする実際のCSSプロパティもありません。

編集:DOM仕様を深く掘り下げて、私は DOMレベル2スタイルカウンターインターフェース を見つけました。これは、少なくともa)現在のカウンター値へのアクセスを許可し、b)Firefoxに実装されているようです。ただ、使い方がわかりません。私の現在のアプローチは、このFirebugの出力後に悲劇的に死にました。

// should return a DOM 2 Counter interface implementation...
window.getComputedStyle(fig_a_element, ':after')
      .getPropertyCSSValue("counter-increment")[0]
      .getCounterValue();

[Exception... "Modifications are not allowed for this document" code: "7"
 nsresult: "0x80530007 (NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR)"
 location: "http://localhost/countertest.html Line: 71"]

どんなアイデアでも、これをどのように実現できるかを高く評価します。

編集2:どうやら私はDOMレベル2スタイルのCounterオブジェクトを誤って解釈しました。また、現在のカウンタ値を返すプロパティもありません。これにより、上記のアプローチは無効になります。

新しいアプローチ:DOMを介して疑似要素のコンテンツを読み取る可能性はありますか?つまり、疑似要素(treeWalkerが頭に浮かぶ)を選択して、そのnodeValueを取得できますか? (ここで'jQuery'と入力し始めたら、その用語を'Sizzle' ...に変更することを再検討してください)

55
Boldewyn

実際のライブ値にアクセスするためのインターフェースが見つかりません。 【カウンターの】

ええあるとは思いません。ごめんなさい。

ドキュメントで要素の前にあるすべての要素(その:before/:after疑似要素を含む)を調べ、カウンターを探し、そこにある数を合計することだけが考えられます。

明らかにそれは恐ろしいです。ブラウザ独自のcounterメカニズムを再現しようとする場合は、それを独自のスクリプトに置き換える方がおそらく簡単です(IE <= 7のカウンター/コンテンツサポートがないため、はるかに互換性があります)。ベースのカウンター。例えば。次のようなもの:

<a href="#prettypicture">this</a>

<div class="counter level=0">...</div>
<img id="prettypicture" class="counter level=1" alt="ooo, pretty"/>
window.onload= function() {
    var counters= Node_getElementsByClassName(document.body, 'counter');
    var indices= [];
    for (var counteri= 0; counteri<counters.length; counteri++) {
        var counter= counters[counteri];

        var level= Element_getClassArgument(counter, 'level');
        while (indices.length<=level)
            indices.Push(0);
        indices[level]++;
        indices= indices.slice(level+1);
        var text= document.createTextNode('Figure '+indices.join('.'));
        counter.parentNode.insertBefore(text, counter.nextSibling);

        if (counter.id!=='') {
            for (var linki= document.links.length; linki-->0;) {
                var link= document.links[i];
                if (
                    link.hostname===location.hostname && link.pathname===location.pathname &&
                    link.search===location.search && link.hash==='#'+counter.id
                ) {
                    var text= document.createTextNode('('+indices.join('.')+')');
                    link.parentNode.insertBefore(text, link.nextSibling);
                }
            }
        }
    }
};
22
bobince

これを読む:

生成されたコンテンツはドキュメントツリーを変更しません。特に、それはドキュメント言語プロセッサにフィードバックされません(例えば、再解析のために)。


スタイルシートで指定されたコンテンツは、DOMの一部にはなりません。

そのため、この場合 getComputedStyleはこの場合機能しません;私は唯一の方法だと思います、誰かが下で説明したようにクラシックループスルーを実行することです!

15
Luca Filosofi

私はあなたのcssをJavascriptに移植します、これはあなたが図のキャプションを得るのを可能にし、そしてまたあなたはより広いブラウザカバレッジを得るでしょう。 jQueryを使用すると、次のようになります。

$(function() {
  var section = 0;
  $(".section").each(function() {
    section++;
    var figure = 0;
    $(this).find("img.figure").each(function() {
      figure++;
      var s = "Fig. " + section + "." + figure;
      $(this).attr({alt:s}).after(s);
    });
  });
});

それからあなたは行うことができます:

<div class="section">blabla <img id="foo" src="http://www.example.com/foo.jpg"></div>
<p>Lorem ipsum dolor sit amet <a href="#foo" class="figurereference">see here</a></p>

<script type="text/javascript">
  $(function() {
    $("a.figurereference").each(function() {
      var selector = $(this).attr("href");
      var $img = $(selector);
      var s = $(this).text() + " (" + $img.attr("alt") + ")";
      $(this).text(s);
    });
  });
</script>

CSSを使用してこれを行うのは非常に便利だと私は同意します。

1
svinto

実際のライブ値にアクセスするためのインターフェースが見つかりません。

window.getComputedStyleから値を取得できない場合は、不可能と思われます。

さらに重要なことは、それは可能ですが、この時点でコンテンツとプレゼンテーションの間の障壁を打ち破っているので、これはCSSを悪用している可能性があると思います。

この関連質問をチェックしてください CSSの「コンテンツ」プロパティの適切な用途は何ですか?

0
Justin Johnson