0

Clone DOM node and inline applied CSS

Function JavaScript 1 revisions 42 20 days ago 20 days ago
/* @problem: Sometimes .cloneNode(true) doesn't copy the styles and your are left
 * with everything copied but no styling applied to the clonedNode (it looks plain / ugly). Solution:
 * 
 * @solution: call synchronizeCssStyles to copy styles from source (src) element to
 * destination (dest) element.
 * 
 * @author: Luigi D'Amico (www.8bitplatoon.com)
 * 
 */
function synchronizeCssStyles(src, destination, recursively) {

    // if recursively = true, then we assume the src dom structure and destination dom structure are identical (ie: cloneNode was used)

    // window.getComputedStyle vs document.defaultView.getComputedStyle 
    // @TBD: also check for compatibility on IE/Edge 
    destination.style.cssText = document.defaultView.getComputedStyle(src, "").cssText;

    if (recursively) {
        const vSrcElements = src.getElementsByTagName("*");
        const vDstElements = destination.getElementsByTagName("*");

        for (var i = vSrcElements.length; i--;) {
            const vSrcElement = vSrcElements[i];
            const vDstElement = vDstElements[i];
//          console.log(i + " >> " + vSrcElement + " :: " + vDstElement);
            vDstElement.style.cssText = document.defaultView.getComputedStyle(vSrcElement, "").cssText;
        }
    }
}

This function copies applied styles through classes and inlines them to an element clone.

Clone a DOM element:

const someDiv = document.getElementById('some-div');
const cloned = someDiv.cloneNode(true); // true to clone recursively

Notice that styles aren't copied along. Then:

synchronizeCssStyles(someDiv, cloned, true);

Now, cloned has styles inlined and is no longer dependent on the externally loaded CSS.

Note: HTML output is HUGE.