Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I clone an HTML element's style object using JavaScript or jQuery?

I'm trying to clone the style object of an element. This should allow me to reset the styles of said element after I change them.

For example:

el.style.left;      // 50px
curr_style.left;    // 50px;

/* 
Modify the elements style.
The cloned style should still hold the original properties from when it was cloned.
*/
el.style.left = '20px';
curr_style.left // should still return 50px.

I first tried to copy it by assigning a variable to the value of el.style. Unfortunately, this points to it by reference and any changes to the style are reflected in the cloned object.

My other attempt involved using jQuery's object extend method to create a copy as such:

var curr_style = $.extend( {}, el.style );

This doesn't seem to work as curr_style.left etc. return undefined.

Any help would be appreciated!

I ended up doing this to retrieve each property: (based on advice from @Raynos)

$.fn.getStyle = function(){
    var style,
    el = this[0];

    // Fallbacks for old browsers.
    if (window.getComputedStyle) {
        style = window.getComputedStyle( el );
    } else if (el.currentStyle) {
        style = $.extend(true, {}, el.currentStyle);
    } else {
        style = $.extend(true, {}, el.style);
    }

    // Loop through styles and get each property. Add to object.
    var styles = {};
    for( var i=0; i<style.length; i++){
        styles[ style[i] ] = style[ style[i] ];
    }

    return styles;
};
like image 452
Adam Hutchinson Avatar asked Jun 02 '11 09:06

Adam Hutchinson


2 Answers

var curr_style;
if (window.getComputedStyle) {
    curr_style = window.getComputedStyle(el);
} else if (el.currentStyle) {
    curr_style = $.extend(true, {}, el.currentStyle);
} else {
    throw "shit browser";
}

style has non-enumerable properties which makes .extend fall over. You want to use the getComputedStyle method to get the styles of an element.

You also want to support older versions of IE by extending el.currentStyle which does have enumerable properties.

The first argument (when set to true) tells jQuery to do a deep clone.

like image 78
Raynos Avatar answered Sep 29 '22 07:09

Raynos


For the purpose of simply resetting styles, I'd suggest just using the cssText (also see MDN) property of the style object. This works in all major browsers and is nice and simple.

jsFiddle:

http://jsfiddle.net/timdown/WpHme/

Example code:

// Store the original style
var originalCssText = el.style.cssText;

// Change a style property of the element
el.style.fontWeight = "bold";

// Now reset
el.style.cssText = originalCssText;
like image 31
Tim Down Avatar answered Sep 29 '22 09:09

Tim Down