Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I fetch the value of a non-standard CSS property via Javascript?

Tags:

javascript

css

I am trying to read a custom (non-standard) CSS property, set in a stylesheet (not the inline style attribute) and get its value. Take this CSS for example:

#someElement {
  foo: 'bar';
}

I have managed to get its value with the currentStyle property in IE7:

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

But currentStyle is MS-specific. So I tried getComputedStyle() in Firefox 3 and Safari 3:

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

...and it returns undefined. Does anyone know a cross-browser way of retreiving a custom CSS property value?

(As you might have noticed, this isn't valid CSS. But it should work as long as the value follows the correct syntax. A better property name would be "-myNameSpace-foo" or something.)

like image 473
joolss Avatar asked Oct 30 '08 12:10

joolss


People also ask

Can we change CSS properties values using JavaScript?

CSS variables have access to the DOM, which means that you can change them with JavaScript.

How do you retrieve a CSS property value of an element?

The attr() CSS function is used to retrieve the value of an attribute of the selected element and use it in the stylesheet. It can also be used on pseudo-elements, in which case the value of the attribute on the pseudo-element's originating element is returned.

Can JavaScript access CSS?

The stylesheet object is available through JavaScript, and allows you to access information about a style sheet referenced from the current web page, such as if it is disabled, its location, and the list of CSS rules it contains.

How do you access styles in JavaScript?

First, you need to select the element with querySelector . Then, you use getComputedStyle to get the element's styles. If you log style , you should see an object that contains every CSS property and their respective values. You can also see this object in Chrome's and Firefox's dev tools.


1 Answers

Modern browsers will just throw away any invalid css. However, you can use the content property since it only has effect with :after, :before etc. You can store JSON inside it:

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

Then use code like this to retrieve it:

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

Note, this is only for modern browsers. Demo: http://jsfiddle.net/xFjZp/3/

like image 112
Esailija Avatar answered Oct 19 '22 20:10

Esailija