First approach
This is how I decided it from the beginning ... calling Mozilla is differently tempting, but it will require sniffing the browser, so we will work without being able to access the cloning style.
Creating two arrays of objects that have unique identifiers - will first contain elements for copying the style from and for the second holding of cloned elements to which the style will be transferred:
var individual = [], singular = []; $('.target').find('[id]').each(function() { individual.push(this); }) .end().clone().find('[id]').each(function() { singular.push(this); });
Now the properties and their values ββare copied from the array of objects that were stored inside the DOM for clones - after that, the name of the current identifier changes to something unique:
$.each(individual, function(key) { var tag = this.id, styles = window.getComputedStyle(this, null), element = singular[key]; $.each(styles, function() { var value = styles.getPropertyValue(this); $(element).css(this, value); }); $(element).attr('id', tag + '-cloned'); });
After that, the cloned element is inserted, so double identifiers are not present. Please note that this can lead to many style properties (for example, around 220 for each object in Firefox).
Demo
var individual = [], singular = []; $('.target').find('[id]').each(function() { individual.push(this); }) .end().clone().find('[id]').each(function() { singular.push(this); }) .end().queue(function() { transFigure(); $(this).dequeue(); }) .appendTo('body'); function transFigure() { $.each(individual, function(key) { var tag = this.id, styles = window.getComputedStyle(this, null), element = singular[key]; $.each(styles, function() { var value = styles.getPropertyValue(this); $(element).css(this, value); }); $(element).attr('id', tag + '-cloned'); }); }
++++++++++++++++++++++++++++++++++++++++++++++++++ +++ ++++++++++++++++++++++++
Second approach
Although the above works fine, it is not very effective, and the page resizing values ββmay start to vary. Thus, I found a better solution after I came across it and then did some digging on JavaScript cssRules . With this, you can directly access all style sheets!
Below is a pen that tries to explain the process, but it comes down to matching (with .test ) the unique identifiers inside the clone from cssText found inside the stylesheet. Then change the id value and save it in an array so that it is subsequently inserted / added to the stylesheet.
A pen
Besides a more efficient approach (without passing all the default values), the actual CSS is copied for all browsers instead of the calculated value. And any derivatives like img , p and such may also be included. It even copies @rules and remains responsive in this way.
Its essence:
var singular = [], rules = []; $('#target').clone().find('[id]').each(function() { singular.push(this); }); var sheet = document.styleSheets[0], styles = sheet.cssRules; $.each(singular, function() { var selector = '#' + this.id, pattern = new RegExp(selector + '(:| |,)'); $.each(styles, function() { var string = this.cssText; if (pattern.test(string)) { var rule = string.replace(selector, selector + '-duplicate'); rules.push(rule); } }); }); $.each(rules, function() { var index = styles.length; sheet.insertRule(this, index); });
After that, the clone can be inserted into the DOM with all the unique identifiers and full style. Please note that in the above example, this was not actually done in order to simplify the code as much as possible when it comes to using cssRules . The image was placed in the markup in advance using another id - one that will correspond to the copied style rules.