2008-10-30 18 views
14

Estoy tratando de leer una propiedad de CSS personalizada (no estándar), establecer en una hoja de estilo (no el atributo de estilo en línea) y obtener su valor. Tome este CSS por ejemplo:¿Puedo obtener el valor de una propiedad de CSS no estándar a través de Javascript?

#someElement { 
    foo: 'bar'; 
} 

He conseguido que su valor con la propiedad currentStyle en IE7:

var element = document.getElementById('someElement'); 
var val = element.currentStyle.foo; 

Pero es currentStyle-MS específica. Así que traté getComputedStyle() en Firefox 3 y Safari 3:

var val = getComputedStyle(element,null).foo; 

... y vuelve indefinida. ¿Alguien conoce una forma de navegador cruzado de recuperar un valor de propiedad de CSS personalizado?

(Como habrá notado, esto no es válido CSS. Pero debería funcionar siempre y cuando el valor sigue la sintaxis correcta. Un mejor nombre de la propiedad sería "-myNameSpace-foo" o algo así.)

+2

Estoy interesado; ¿Que problema estas tratando de resolver? :) – roosteronacid

+2

¡Lo mismo! Parece una petición muy extraña ... –

+1

Pensé que sería estupendo llevar la configuración relacionada con el estilo para cosas que no sean HTML (como Flash, Silverlight o JS-cosas) en hojas de estilo normales, y luego pasarlas a, p. Destello a través de JS. En un entorno grande donde el contenido complejo debe ser controlado por estilo solo con hojas de estilo, esto podría ser valioso. – joolss

Respuesta

9

Firefox no se traslada etiquetas, atributos o estilos CSS que no entiende a partir del código para el DOM. Eso es por diseño. Javascript solo tiene acceso al DOM, no al código. Así que no, no hay forma de acceder a una propiedad desde JavaScript que el navegador no admita.

+1

Eso no es estrictamente cierto. Firefox no crea propiedades DOM para atributos HTML no estándar, pero son accesibles a través de * getAttribute *. – RobG

4

Mediante la lectura de la información de estilo en el IE, usted puede obtener estas propiedades "falsos", pero sólo en IE que yo sepa.

var firstSS = document.styleSheets[0]; 
var firstSSRule = firstSS.rules[0]; 
if(typeof(firstSSRule.style.bar) != 'undefined'){ 
    alert('value of [foo] is: ' + firstSSRule.style.bar); 
} else { 
    alert('does not have [foo] property'); 
} 

Su código es feo, pero ya entiendo la imagen.

+1

¡Buen truco! Mi ejemplo anterior también funciona bien en IE pero en ningún otro lugar (ver currentStyle en http://www.quirksmode.org/dom/w3c_css.html) aunque necesita un elemento que coincida con el selector (el modo CSS) Una forma sería ser analizar la hoja de estilo a través de Javascript. No se siente práctico sin embargo. – joolss

+0

¡Guau! Solución realmente difícil, ¡pero bien! –

2

Una forma sería, por supuesto, para escribir su propio CSS-analizador en Javascript. Pero creo que es realmente en la parte superior.

+0

Definitivamente en la parte superior, pero esta es una sugerencia útil en situaciones desesperadas :). –

3

yo también tener algunas páginas que funcionan maravillosamente en MSIE, pero tienen un montón de información en estilos y hojas de estilo. Así que estoy pensando en soluciones temporales. Una cosa que Firefox permite, misericordiosamente, es poner atributos en línea en el DOM. Así que aquí hay una estrategia parcial:

  1. reemplazar cada estilo en línea en el documento html con el correspondiente "nStyle", por ejemplo, < span class = "CLS1" nStyle = "color: red; nref: #myid; foo: bar "> ... </span>

  2. Cuando se carga la página, haga lo siguiente en cada nodo de elemento: (a) copiar el valor del atributo en nStyle cssText de la etiqueta, y al mismo tiempo (b) convierta los atributos no estándar en un formato más fácil, de modo que, por ejemplo, node.getAttribute ('nStyle') se convierta en el objeto {"nref": "# myid", "foo": "bar"}.

  3. escribir una función de "calculatedStyle" que recibe ya sea el estilo o la nStyle, dependiendo de lo que está disponible.

Escribir un analizador difícil para las hojas de estilo podrían permitir una estrategia similar para ellos, pero tengo una pregunta: ¿Cómo puedo superar el obstáculo de la lectura de la hoja de estilo sin censura de Firefox?

12

Los navegadores modernos simplemente tirar a la basura cualquier css válido.Sin embargo, puede utilizar la propiedad de contenido, ya que sólo tiene efecto con :after, :before etc. Puede almacenar JSON en su interior:

#someElement { 
    content: '{"foo": "bar"}'; 
} 

A continuación, utilice un código como éste para recuperarlo:

var CSSMetaData = function() { 

    function trimQuotes(str) { 
     return str.replace(/^['"]/, "").replace(/["']$/, ""); 
    } 

    function fixFirefoxEscape(str) { 
     return str.replace(/\\"/g, '"'); 
    } 

    var forEach = [].forEach, 
     div = document.createElement("div"), 
     matchesSelector = div.webkitMatchesSelector || 
          div.mozMatchesSelector || 
          div.msMatchesSelector || 
          div.oMatchesSelector || 
          div.matchesSelector, 
     data = {}; 

    forEach.call(document.styleSheets, function(styleSheet) { 
     forEach.call(styleSheet.cssRules, function(rule) { 
      var content = rule.style.getPropertyValue("content"), 
       obj; 

      if(content) { 
       content = trimQuotes(content); 
       try { 
        obj = JSON.parse(content); 
       } 
       catch(e) { 
        try { 

         obj = JSON.parse(fixFirefoxEscape(content)); 
        } 
        catch(e2) { 
         return ; 
        } 

       } 
       data[rule.selectorText] = obj; 
      } 
     }); 

    }); 


    return { 

     getDataByElement: function(elem) { 
      var storedData; 
      for(var selector in data) { 
       if(matchesSelector.call(elem, selector)) { 
        storedData = data[selector]; 
        if(storedData) return storedData; 

       } 
      } 

      return null; 
     } 
    }; 

}(); 
var obj = CSSMetaData.getDataByElement(document.getElementById("someElement")); 
console.log(obj.foo); //bar 

Tenga en cuenta que esto es solo para navegadores modernos. Demostración: http://jsfiddle.net/xFjZp/3/

+0

No funciona con Opera, que aplica la propiedad de contenido no solo en pseudoelementos: en lugar del contenido real, se muestra el JSON. – Bergi

+0

@Bergi, sí, pero eso es un error entonces. Ver especificación http://www.w3.org/TR/CSS21/generate.html#content – Esailija

+0

OK, presenté un informe :-) Sin embargo, [la prueba oficial] (http://test.csswg.org/suites) /css2.1/20110323/xhtml1/content-applies-to-001.xht) pasa para ambos comportamientos ... – Bergi

-1

Quizás puedas probar con LESS. Es el lenguaje de Hojas de estilo dinámicas y puede crear atributos de CSS no estándar, que se compilarán más adelante.

Cuestiones relacionadas