如何使用JavaScript访问CSS生成的内容

如何使用JavaScript访问CSS生成的内容,javascript,css,dom,counter,Javascript,Css,Dom,Counter,我使用CSS的计数器和内容属性生成标题和数字的编号: img.figure:after { counter-increment: figure; content: "Fig. " counter(section) "." counter(figure); } 这(假设适当的浏览器)在任何图像之后都会给出一个很好的标签“图1.1”、“图1.2”等等 问题:我如何从Javascript访问它?问题是双重的,因为我想访问某个计数器(在某个DOM节点)的当前值或CSS生成的内容(在某个DOM节

我使用CSS的
计数器
内容
属性生成标题和数字的编号:

img.figure:after {
  counter-increment: figure;
  content: "Fig. " counter(section) "." counter(figure);
}
这(假设适当的浏览器)在任何图像之后都会给出一个很好的标签“图1.1”、“图1.2”等等

问题:我如何从Javascript访问它?问题是双重的,因为我想访问某个计数器(在某个DOM节点)的当前值或CSS生成的内容(在某个DOM节点)的值,或者,很明显,这两个信息

背景:我想在链接后面加上适当的数字,如下所示:

<a href="#fig1">see here</h>
------------------------^ " (Fig 1.1)" inserted via JS
$(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);
    });
  });
});
但是,这不是live值,而是样式表中声明的值。我找不到任何接口来访问真实的实时值。在计数器的情况下,甚至没有真正的CSS属性可查询

编辑:在DOM规范中越来越深入地挖掘,我发现。这似乎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样式的计数器对象。它也没有返回当前计数器值的属性。这使得上述方法无效

新方法:是否有可能通过DOM读取伪元素的内容?也就是说,我可以选择伪元素(
treeWalker
),然后获取它的
nodeValue
?(如果您现在开始键入'jQuery',请重新考虑将该术语更改为'Sizzle'…)

我找不到任何接口来访问真实的实时值

如果无法从
window.getComputedStyle
中获取值,那么这似乎是不可能的

更重要的是,虽然它可以做到这一点,但我认为这可能是滥用CSS,因为此时您正在打破内容和表示之间的障碍

看看这个相关的问题

我找不到任何接口来访问真实的实时值。[柜台的]

嗯。我想没有。对不起

我能想到的唯一一件事就是在文档中的元素之前遍历每个元素(包括它的
:before
/
:after
伪元素),查找计数器并计算有多少计数器


很明显,那太可怕了。如果您要尝试重现浏览器自己的
计数器
机制,可能会更容易(而且更兼容,因为IE我会将css移植到Javascript,这使您能够获得图形标题,也可以获得更大的浏览器覆盖率。使用jQuery,您可以执行以下操作:

<a href="#fig1">see here</h>
------------------------^ " (Fig 1.1)" inserted via JS
$(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>
blabla
Lorem ipsum dolor sit amet

$(函数(){ $(“a.figurereference”)。每个(函数(){ var选择器=$(this.attr(“href”); 变量$img=$(选择器); var s=$(this.text()+”(“+$img.attr(“alt”)+”); $(本).text(s); }); });
尽管我同意使用CSS做这件事会非常整洁。

阅读以下内容:

生成的内容不会改变 文档树。尤其是 未反馈到文档语言 处理器(例如,用于重新分类)


样式表中指定的内容不会成为DOM的一部分


因此,基于这个原因,在这种情况下不起作用;我认为唯一的方法,就是像下面有人所描述的那样,通过执行一个经典的循环!

我不认为,我以任何方式滥用CSS。如果我这样做了,为什么CSS 2.1规范中生成的内容章节会是这样的呢?嗯,这是风格的问题,我如何标记我的图形。它不是图形本身信息的重要部分,它前面是字符串“Fig.1:”。我可以将其标记为“1.1”或“Fig.1”或其他任何东西,这只是一种扩展的要点(我认为,你同意,这真的只是风格)。如果只是在列表的上下文中,如果它是一个新列表项的指示,我会同意项目符号类比;否则,这是一个标题,而标题是内容。此外,不管规范怎么说,它仍然违反了内容和表示分离的理念。但是,如果这不是一个问题,我能阻止谁;)实际上,我省略了标题,从而简化了上述示例。在实际情况中,“Fig 1.1”作为实际图形标题的前缀(如
这是Foo的图像)。否则,我同意你的观点,CSS生成的内容可能被滥用来注入语义上有意义的内容,这是一件不好的事情。我想在你回答后我更新了这个问题。否则,我同意我不想在任意数量的元素中循环,只是为了找到它们的
内容
计数器增量
CSS属性。
getCounterValue
并不像听起来那样。这是一种笨拙的类型安全方法,他们实现了将不同类型的解析CSS声明值作为结构化对象的思想
getCounterValue
实际上意味着“作为
计数器
对象获取CSS属性值”。
计数器
对象只是一个表示CSS声明的值类型,您无法从中获取实际的计数器编号。是的,在重新读取规范后,显然计数器对象没有当前值的属性。该死“从不”是一个强有力的词。显然,有一个旧的但不足以设置值样式的API(没有访问计数器的权限),但正如我所知,有一个新的API可以从DOM中访问样式设置信息。我不会失去希望,总有一天会的
<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>