JQuery CSS plugin that returns the computed element style for pseudo-cloning of this element?

I am looking for a way to use jQuery to return a computed styles object for a 1st matched element. Then I could pass this object to another jQuery css method call.

For example, with width, I can do the following to make 2 divs of the same width:

$('#div2').width($('#div1').width()); 

It would be nice if I could make the text input look like an existing range :

 $('#input1').css($('#span1').css()); 

where .css () without an argument returns an object that can be passed . css (obj) .

(I cannot find the jQuery plugin for this, but it seems to exist. If it does not exist, I will turn mine below into a plugin and put it with all the properties that I use.)

Basically, I want to pseudo-clone certain elements , but use a different tag . For example, I have an li element that I want to hide and put an input element on it that looks the same. When the user types, it looks like they are editing the inline element .

I am also open to other approaches to this pseudo-cloning issue for editing. Any suggestions?

Here is what I have now. The only problem is just getting all the possible styles. It can be a ridiculously long list.




 jQuery.fn.css2 = jQuery.fn.css; jQuery.fn.css = function() { if (arguments.length) return jQuery.fn.css2.apply(this, arguments); var attr = ['font-family','font-size','font-weight','font-style','color', 'text-transform','text-decoration','letter-spacing','word-spacing', 'line-height','text-align','vertical-align','direction','background-color', 'background-image','background-repeat','background-position', 'background-attachment','opacity','width','height','top','right','bottom', 'left','margin-top','margin-right','margin-bottom','margin-left', 'padding-top','padding-right','padding-bottom','padding-left', 'border-top-width','border-right-width','border-bottom-width', 'border-left-width','border-top-color','border-right-color', 'border-bottom-color','border-left-color','border-top-style', 'border-right-style','border-bottom-style','border-left-style','position', 'display','visibility','z-index','overflow-x','overflow-y','white-space', 'clip','float','clear','cursor','list-style-image','list-style-position', 'list-style-type','marker-offset']; var len = attr.length, obj = {}; for (var i = 0; i < len; i++) obj[attr[i]] = jQuery.fn.css2.call(this, attr[i]); return obj; } 

Edit: I have been using the code above for some time now. It works well and behaves exactly the same as the original css method with one exception: if 0 arguments are passed, it returns an object with a computed style.

As you can see, it immediately calls the original css method, if applicable. Otherwise, it gets the computed styles of all the listed properties (compiled from the list of classified Firebug styles). Although he receives a long list of values, he is pretty quick. Hope this is helpful to others.

+67
javascript jquery css web-applications
Jun 16 '09 at 23:56
source share
9 answers

Two years later, but I have the solution you are looking for. Here's the plugin I wrote (by wrapping another guy function in a plugin format) that does exactly what you want, but gets all the styles possible 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(/\-([az])/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); 

The main use is pretty simple:

 var style = $("#original").getStyleObject(); // copy all computed CSS properties $("#original").clone() // clone the object .parent() // select it 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 this helps.

+59
Jun 20 '11 at 19:37
source share

This is not jQuery, but in Firefox, Opera and Safari you can use window.getComputedStyle(element) to get the computed styles for the element, and in IE <= 8 you can use element.currentStyle . The returned objects are different in each case, and I'm not sure how good it is to work with elements and styles created using Javascript, but maybe they will be useful.

In Safari, you can do the following, which is neat:

 document.getElementById('b').style.cssText = window.getComputedStyle(document.getElementById('a')).cssText; 
+20
Jun 20 '09 at 0:11
source share

I don’t know if you are happy with the answers you have received so far, but I wasn’t and you may not have liked mine, but it can help someone else.

After thinking about how to style “clone” or “copy” elements from one to another, I realized that it is not very optimal for approaching a loop through n and applies to n2, but we sort of stuck with it.

When you encounter these problems, you rarely have to copy ALL styles from one element to another ... you usually have a specific reason to require the use of "some" styles.

Here I returned:

 $.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 list of css attributes separated by spaces as the first argument and the node you want to clone as the second argument, for example:

 $('div#copyFrom').copyCSS('width height color',$('div#copyTo')); 

In any case, something seems to “shift” after this, I will try to fix it using style sheets so as not to clutter my Js with too many missing ideas.

+5
Jan 28 '10 at 15:45
source share

Now that I have had time to study the problem and better understand how the jQuery internal css method works, what I posted seems to work well enough for the used case that I mentioned.

It has been suggested to solve this problem with CSS, but I think this is a more generalized solution that will work anyway without the need to add delete classes or update your css.

I hope others find this helpful. If you find an error, let me know.

+4
Jun 21 '09 at 7:32
source share

I like your answer Quickredfox. I needed to copy some CSS, but not right away, so I changed it to make "toNode" optional.

 $.fn.copyCSS = function( style, toNode ){ var self = $(this), styleObj = {}, has_toNode = typeof toNode != 'undefined' ? true: false; if( !$.isArray( style ) ) { style=style.split(' '); } $.each( style, function( i, name ){ if(has_toNode) { toNode.css( name, self.css(name) ); } else { styleObj[name] = self.css(name); } }); return ( has_toNode ? self : styleObj ); } 

If you call it like this:

 $('div#copyFrom').copyCSS('width height color'); 

It will then return an object with your CSS declarations, which you can use later:

 { 'width': '140px', 'height': '860px', 'color': 'rgb(238, 238, 238)' } 

Thanks for the starting point.

+3
Oct 07 '10 at 13:21
source share

Multipurpose .css()

Using

 $('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 

The code

 (function($) { // Monkey-patching original .css() method var nativeCss = $.fn.css; var camelCase = $.camelCase || function(str) { return str.replace(/\-([az])/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); 

The basic idea is taken from the answers of Dakota's and HexInteractive .

+3
Jun 20 '13 at 16:20
source share

Great feature provided by OP. I slightly modified it so that you can choose which values ​​you want to return.

 (function ($) { var jQuery_css = $.fn.css, gAttr = ['font-family','font-size','font-weight','font-style','color','text-transform','text-decoration','letter-spacing','word-spacing','line-height','text-align','vertical-align','direction','background-color','background-image','background-repeat','background-position','background-attachment','opacity','width','height','top','right','bottom','left','margin-top','margin-right','margin-bottom','margin-left','padding-top','padding-right','padding-bottom','padding-left','border-top-width','border-right-width','border-bottom-width','border-left-width','border-top-color','border-right-color','border-bottom-color','border-left-color','border-top-style','border-right-style','border-bottom-style','border-left-style','position','display','visibility','z-index','overflow-x','overflow-y','white-space','clip','float','clear','cursor','list-style-image','list-style-position','list-style-type','marker-offset']; $.fn.css = function() { if (arguments.length && !$.isArray(arguments[0])) return jQuery_css.apply(this, arguments); var attr = arguments[0] || gAttr, len = attr.length, obj = {}; for (var i = 0; i < len; i++) obj[attr[i]] = jQuery_css.call(this, attr[i]); return obj; } })(jQuery); 

Choose which values ​​you want by specifying your own array: $().css(['width','height']);

+2
Feb 18 '12 at 1:22
source share

I just wanted to add the extension to the code provided by Dakota.

If you want to clone an element with all the styles applied to it and all child elements, you can use the following code:

 /* * 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(/\-([az])/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(); } $.fn.cloneWithCSS = function() { styles = {}; $this = $(this); $clone = $this.clone(); $clone.css( $this.getStyleObject() ); children = $this.children().toArray(); var i = 0; while( children.length ) { $child = $( children.pop() ); styles[i++] = $child.getStyleObject(); $child.children().each(function(i, el) { children.push(el); }) } cloneChildren = $clone.children().toArray() var i = 0; while( cloneChildren.length ) { $child = $( cloneChildren.pop() ); $child.css( styles[i++] ); $child.children().each(function(i, el) { cloneChildren.push(el); }) } return $clone } })(jQuery); 

Then you can simply do: $clone = $("#target").cloneWithCSS()

+2
Jan 22 '14 at 9:13
source share
 $.fn.cssCopy=function(element,styles){ var self=$(this); if(element instanceof $){ if(styles instanceof Array){ $.each(styles,function(val){ self.css(val,element.css(val)); }); }else if(typeof styles==="string"){ self.css(styles,element.css(styles)); } } return this; }; 

Usage example

 $("#element").cssCopy($("#element2"),['width','height','border']) 
0
Nov 02 '10 at 20:12
source share



All Articles