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

我使用CSS的countercontent属性生成我的标题和数字的编号:

 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 

据我所知,可以归结为这个问题:我可以通过getComputedStyle访问contentcounter-increment

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

但是,这不是实时值,而是样式表中声明的值。 我找不到任何接口来访问真正的实时价值。 在计数器的情况下,甚至没有一个真正的CSS属性来查询。

编辑:通过DOM规范挖掘越来越深,我find了DOM Level 2样式计数器接口 。 这似乎a)允许访问当前的计数器值和b)至less在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读取伪元素的内容? 也就是说,我可以select伪元素( treeWalker想到),然后得到它的nodeValue ? (如果您现在开始键入“jQuery” ,请重新考虑将该术语更改为“Sizzle”

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

是啊。 我不认为有一个。 抱歉。

我能想到的唯一办法是在文档中的元素:before遍历每个元素(包括:before / :after伪元素),查找计数器并合计多less个元素。

显然这是可怕的。 如果您要尝试重现浏览器自身的counter机制,那么使用您自己的基于脚本的计数器replace它可能会更容易(并且在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); } } } } }; 

读这个:

生成的内容不会改变文档树。 特别是,它不被反馈给文档语言处理器(例如,用于重新分析)。


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

所以出于这个原因getComputedStyle 在这种情况下将不起作用 ; 我认为唯一的方法就是像下面所描述的那样进行一个经典循环

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

如果你无法从window.getComputedStyle获取值,那么看起来这是不可能的。

更重要的是,虽然它可以做到这一点,但我认为这可能会滥用CSS,因为您已经打破了内容和呈现之间的障碍。

看看这个相关的问题有什么好用的CSS“内容”属性?

我会将您的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来做这件事是非常整洁的。

我不知道它是如何实现的,但jquery .css()select器似乎在最新版本的safari,chrome和firefox上工作。

 .foo { content: 'hello'; } 

 var value = $('.foo').css('content').toString(); 

这里有一支笔直接从CSS注入SVG图标; http://codepen.io/shadowmint/pen/unvLB

(请注意,内容值必须转义;即'1';使用内容:1将不起作用)