2010-04-16 29 views
51

genero la numeración de mis encabezados y cifras con counter y content propiedades de CSS:Cómo acceder a la CSS contenido generado con JavaScript

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

Este (navegador apropiado error u omisión) da un buen etiquetado "Fig. 1.1", "Fig. 1.2" y así sucesivamente siguiendo cualquier imagen.

Pregunta: ¿Cómo puedo acceder a esto desde Javascript? La pregunta es doble en cuanto a que me gustaría acceder al el valor actual de un determinado contador (en un determinado nodo DOM) o el valor del contenido generado por CSS (en un determinado nodo DOM) o, obviamente, ambas informaciones.

Antecedentes: me gustaría añadir a los enlaces de respaldo que hacen referencia a las cifras del número apropiado, como esto:

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

Por lo que yo puedo ver, que se reduce a este problema: yo podía acceso content o counter-increment través getComputedStyle:

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

sin embargo, este no es el en vivo valor, pero el declarado en la hoja de estilo. No puedo encontrar ninguna interfaz para acceder al real en vivo. En el caso del contador, ni siquiera hay una propiedad de CSS real para consultar.

Editar: Cavando más y más a través de las especificaciones DOM, encontré the DOM Level 2 Style Counter interface. Esto parece a) permitir el acceso al valor del contador actual yb) implementarse en Firefox, al menos. Sin embargo, no tengo idea de cómo usarlo. Mi enfoque actual murió trágicamente después de esta salida 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"] 

Cualquier idea, cómo esto podría ser traído a la vida sería muy apreciada.

Editar 2: Aparentemente malinterpreté el objeto Counter del estilo DOM Nivel 2. Tampoco tiene propiedad para devolver el valor del contador actual. Esto hace que el enfoque anterior sea inválido.

Nuevo enfoque: ¿Existe la posibilidad de leer el contenido de un pseudo-elemento a través del DOM? Es decir, ¿puedo seleccionar el pseudo-elemento (me viene a la mente treeWalker) y luego obtener su nodeValue? (Si empieza a escribir 'jQuery' ahora, por favor, reconsiderar cambiar ese término en 'Arden' ...)

+2

'getCounterValue' no hace lo que suena. Es una forma poco segura y segura para los tipos que han implementado la idea de obtener diferentes tipos de valores de declaración de CSS analizados como objetos estructurados. 'getCounterValue' en realidad significa" obtener valor de propiedad CSS, como un objeto 'Counter'". El objeto 'Contador' es solo un tipo de valor que representa la declaración de CSS, no puede obtener el número de contador real de la misma. – bobince

+0

Sí, después de volver a leer la especificación, aparentemente el objeto Counter no tiene ninguna propiedad para el valor actual. ¡Maldito! – Boldewyn

Respuesta

19

no puedo encontrar ninguna interfaz para acceder al valor de carne y hueso. [del contador]

Sí. No creo que haya uno. Lo siento.

Lo único que se me ocurre es revisar cada elemento (incluidos sus pseudoelementos :before/:after) antes del elemento en el documento, buscar contadores y sumar cuantos hay.

Obviamente eso es horrible. Si va a tratar de reproducir el mecanismo propio del navegador counter, probablemente sería más fácil (y mucho más compatible, dado que IE < = 7 es la falta de soporte de contador/contenido) simplemente reemplazarlo con sus propios contadores basados ​​en scripts. p.ej. algo a lo largo de las líneas de:

<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); 
       } 
      } 
     } 
    } 
}; 
+0

Parece que, en teoría, * hay * una interfaz para el valor del contador. Creo que actualicé la pregunta después de que respondiste. De lo contrario, acepto que no deseo recorrer una cantidad arbitraria de elementos solo para encontrar su propiedad CSS 'content' o' counter-increment'. – Boldewyn

0

no puedo encontrar ninguna interfaz para acceder al valor de carne y hueso.

Si no puede obtener el valor de window.getComputedStyle, parece que sería imposible.

Lo que es más importante, aunque puede hacerlo, creo que esto podría estar abusando de CSS, ya que en este momento está rompiendo la barrera entre el contenido y la presentación.

Salida esta pregunta relacionada What are good uses of css “Content” property?

+3

No creo que abuse de CSS de ninguna manera. Si lo hiciera, ¿por qué sería el capítulo Contenido generado en la especificación de CSS 2.1? En mi humilde opinión, es una cuestión de * estilo *, cómo etiqueto mi figura. No es parte esencial de la información de la figura * en sí *, que está precedida por la cadena "Fig. 1.1:". Podría etiquetarlo como "1.1" o "Figura 1" o cualquier otra cosa, que es solo una especie de viñeta extendida (y creo que usted acepta que * ese * es realmente solo estilo). – Boldewyn

+0

Para la parte * 'imposible' *: Ese es mi miedo, también, pero la esperanza muere la última ... – Boldewyn

+1

Estoy de acuerdo con la analogía de la viñeta si solo está en el contexto de una lista y si es una indicación de una nueva elemento de lista; de lo contrario, este es un título y los subtítulos son contenido. Además, independientemente de lo que dice una especificación, sigue violando la idea de separación de contenido y presentación. Sin embargo, si esto no es una preocupación, ¿quién soy yo para detenerte;) –

0

lo haría puerto el CSS a Javascript, esto le permite sacar el pie de figura y también se obtiene una mayor cobertura navegador. Usando jQuery que haría algo como esto:

$(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); 
    }); 
    }); 
}); 

entonces se podría hacer:

<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> 

Aunque estoy de acuerdo en que al hacer esto el uso de CSS sería muy ordenado.

14

leyeron:

contenido generado no altera la estructura del documento. En particular, es no retroalimentado al procesador de idioma de documento (por ejemplo, para reparsing).


contenido especificado en una hoja de estilo no se convierta en parte de la DOM.

por esta razón la getComputedStyleno funcionará en este caso; Creo que la única manera es realizar un loop clásico a través de como alguien ha descrito a continuación.

+0

* 'Nunca' * es una palabra fuerte. Aparentemente, había una API antigua, pero insuficiente para los valores de estilo (sin acceso a los contadores), pero como me dijeron, hay un nuevo pensamiento sobre una API nueva para acceder a la información de estilo desde el DOM: http: // lists. w3.org/Archives/Public/www-style/2010Apr/0136.html. No pierdo la esperanza de que algún día funcione. Por el momento, creo que el ciclo auto-escrito es la única posibilidad. – Boldewyn

+0

¡Lo siento, hermano! ¡pero en mi humilde opinión, la IMHO nunca es fuerte en este caso ** simplemente porque está intentando acceder a algo que no se ha creado a nivel de DOM! ;-) –

+0

+1 punto interesante, gracias! –

-1

No estoy seguro de cómo se implementa, pero el selector jquery .css() parece funcionar para esto en la última versión de safari, cromo y firefox.

.foo { content: 'hello'; } 

...

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

Aquí hay un bolígrafo en vivo para inyectar los iconos SVG directamente desde el CSS; http://codepen.io/shadowmint/pen/unvLB

(observe que el valor de contenido debe ser escapado; es decir, '1'; el uso de contenido:. 1 no funcionará)

+1

Como ve, el problema es con los contadores CSS (u otro contenido generado FWIW). No necesito el contador de la cadena '" Fig. "(Sección)". " contador (figura) '(que jQuery y DOM producen) pero' Fig. 1.1' para un elemento concreto, el valor real, visible, insertado, calculado. Esto es inalcanzable desde dentro de JS, hasta donde puedo decir. – Boldewyn

+0

O, para decirlo de otra manera: si puede traer [este violín] (http://jsfiddle.net/boldewyn/LY23Q/) para mostrar '1. 'en el área de texto, las posibilidades son buenas, que acepto tu respuesta y alabo a tu genio en todas las redes sociales a las que puedo acceder ;-) – Boldewyn

Cuestiones relacionadas