I\'m looking for a way using jQuery to return an object of computed styles for the 1st matched element. I could then pass this object to another call of jQuery\'s css method
Two years late, but I have the solution you're looking for. Here's a plugin I wrote (by wrapping another guy's function in plugin format) which does exactly what you want, but gets all possible styles in all browsers, even IE.
jquery.getStyleObject.js:
/*
* getStyleObject Plugin for jQuery JavaScript Library
* From: http://upshots.org/?p=112
*
* Copyright: Unknown, see source link
* Plugin version by Dakota Schneider (http://hackthetruth.org)
*/
(function($){
$.fn.getStyleObject = function(){
var dom = this.get(0);
var style;
var returns = {};
if(window.getComputedStyle){
var camelize = function(a,b){
return b.toUpperCase();
}
style = window.getComputedStyle(dom, null);
for(var i=0;i<style.length;i++){
var prop = style[i];
var camel = prop.replace(/\-([a-z])/g, camelize);
var val = style.getPropertyValue(prop);
returns[camel] = val;
}
return returns;
}
if(dom.currentStyle){
style = dom.currentStyle;
for(var prop in style){
returns[prop] = style[prop];
}
return returns;
}
return this.css();
}
})(jQuery);
Basic usage is pretty simple:
var style = $("#original").getStyleObject(); // copy all computed CSS properties
$("#original").clone() // clone the object
.parent() // select it's parent
.appendTo() // append the cloned object to the parent, after the original
// (though this could really be anywhere and ought to be somewhere
// else to show that the styles aren't just inherited again
.css(style); // apply cloned styles
Hope that helps.
I dont know if you're happy with the answers you got so far but I wasn't and mine may not please you either, but it may help someone else.
After pondering upon how to "clone" or "copy" elements' styles from one to another I have come to realize that it was not very optimal of an approach to loop through n and apply to n2, yet we're sorta stuck with this.
When you find yourself facing these issues, you rarely ever need to copy ALL the styles from one element to another... you usually have a specific reason to want "some" styles to apply.
Here's what I reverted to:
$.fn.copyCSS = function( style, toNode ){
var self = $(this);
if( !$.isArray( style ) ) style=style.split(' ');
$.each( style, function( i, name ){ toNode.css( name, self.css(name) ) } );
return self;
}
You can pass it a space-separated list of css attributes as the first argument and the node you want to clone them to as the second argument, like so:
$('div#copyFrom').copyCSS('width height color',$('div#copyTo'));
Whatever else seems to "misalign" after that, I'll try to fix with stylesheets as to not clutter my Js with too many misfired ideas.
.css()
$('body').css(); // -> { ... } - returns all styles
$('body').css('*'); // -> { ... } - the same (more verbose)
$('body').css('color width height') // -> { color: .., width: .., height: .. } - returns requested styles
$('div').css('width height', '100%') // set width and color to 100%, returns self
$('body').css('color') // -> '#000' - native behaviour
(function($) {
// Monkey-patching original .css() method
var nativeCss = $.fn.css;
var camelCase = $.camelCase || function(str) {
return str.replace(/\-([a-z])/g, function($0, $1) { return $1.toUpperCase(); });
};
$.fn.css = function(name, value) {
if (name == null || name === '*') {
var elem = this.get(0), css, returns = {};
if (window.getComputedStyle) {
css = window.getComputedStyle(elem, null);
for (var i = 0, l = css.length; i < l; i++) {
returns[camelCase(css[i])] = css.getPropertyValue(css[i]);
}
return returns;
} else if (elem.currentStyle) {
css = elem.currentStyle;
for (var prop in css) {
returns[prop] = css[prop];
}
}
return returns;
} else if (~name.indexOf(' ')) {
var names = name.split(/ +/);
var css = {};
for (var i = 0, l = names.length; i < l; i++) {
css[names[i]] = nativeCss.call(this, names[i], value);
}
return arguments.length > 1 ? this : css;
} else {
return nativeCss.apply(this, arguments);
}
}
})(jQuery);
Main idea is taken from Dakota's & HexInteractive's answers.