Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set / Copy javascript computed style from one element to another

So I am trieing to copy all the style that apply on one element ( class / id / tagName / attribute etc. ). So far I found out that I can copy the computed style of an element, Just one problem ... couldend apply it on outher element ;/

or diffrend way to copy all the style.

(this is as far as i got :/ ) http://jsfiddle.net/8KdJd/2/

   //queriks mode + minor changes to retrive the computed style
function getCS(el)
{
    if (el.currentStyle)
        var y = el.currentStyle;
    else if (window.getComputedStyle)
        var y = document.defaultView.getComputedStyle(el,null);
    return y;
}
function setCS(el,cs)
{
    if (el.currentStyle)
    {

        el.currentStyle = cs;
        el.style = cs;
    }
    else if (window.getComputedStyle)
    {el.style = cs 
    }

}


var myLink = document.getElementById('myLink');
var anotherLink = document.getElementById('anotherLink');

var CS_myLink = getCS(myLink);
setCS(anotherLink,CS_myLink);
like image 490
Adi Darachi Avatar asked Nov 05 '13 07:11

Adi Darachi


People also ask

How to set computed style JavaScript?

To set or copy JavaScript computed style from one element to another, we can loop through each style and call the setProperty method to set the styles on the target element. to add a div and a section element. We define the copyNode function that takes the sourceNode and targetNode .

How do you copy an element style?

First, hover over the element you want to copy. Then, right-click on it and choose the option “Inspect”. On the left side is the HTML DOM tree, and on the right side, the CSS styles of the selected element. Having the right element selected on the HTML DOM tree, right-click on it and choose “Copy” > “Copy styles”.

Can JavaScript change the style of an element?

The HTML DOM allows JavaScript to change the style of HTML elements.

What does .style do in JavaScript?

The style property returns the values of an element's style attribute. The style property returns a CSSStyleDeclaration object. The CSSStyleDeclaration object contains all inline styles properties for the element. It does not contain any style properties set in the <head> section or in any external style sheets.


3 Answers

Update: As @icl7126 suggested, here is a shorter version for practically the same usage. good thing to remember that this code would not run on most/older browser if not pre-compiled.

Original (ES 2017):

function copyNodeStyle(sourceNode, targetNode) {
  const computedStyle = window.getComputedStyle(sourceNode);
  Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key)))
}

Precompiled (ES 5):

function copyNodeStyle(sourceNode, targetNode) {
  var computedStyle = window.getComputedStyle(sourceNode);
  Array.from(computedStyle).forEach(function (key) {
    return targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key));
  });
}
#

original answer posted on Nov '13. CSS variables were not supported back then. (first introduces on firefox on Jul 2014)

#

Thats it! I got it :)

Iv'e seen that lots of people view this question, So below is more detailed and clean code.

var copyComputedStyle = function(from,to){
    var computed_style_object = false;
    //trying to figure out which style object we need to use depense on the browser support
    //so we try until we have one
    computed_style_object = from.currentStyle || document.defaultView.getComputedStyle(from,null);

    //if the browser dose not support both methods we will return null
    if(!computed_style_object) return null;

        var stylePropertyValid = function(name,value){
                    //checking that the value is not a undefined
            return typeof value !== 'undefined' &&
                    //checking that the value is not a object
                    typeof value !== 'object' &&
                    //checking that the value is not a function
                    typeof value !== 'function' &&
                    //checking that we dosent have empty string
                    value.length > 0 &&
                    //checking that the property is not int index ( happens on some browser
                    value != parseInt(value)

        };

    //we iterating the computed style object and compy the style props and the values 
    for(property in computed_style_object)
    {
        //checking if the property and value we get are valid sinse browser have different implementations
            if(stylePropertyValid(property,computed_style_object[property]))
            {
                //applying the style property to the target element
                    to.style[property] = computed_style_object[property];

            }   
    }   

};
like image 181
Adi Darachi Avatar answered Sep 24 '22 19:09

Adi Darachi


A bit shorter solution using setProperty, getPropertyValue and getPropertyPriority.

function copyNodeStyle(sourceNode, targetNode) {
  const computedStyle = window.getComputedStyle(sourceNode);
  Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key)))
}

Useful MDN docs: getComputedStyle and CSSStyleDeclaration

like image 43
icl7126 Avatar answered Sep 24 '22 19:09

icl7126


Computed styles do not retain priority information (... !important) so getComputedStyle() will not return style priorities and therefore computedStyle.getPropertyPriority(key) above (in the accepted answer) will not work - it will always return ''.

If you want to ensure the computed styles always take priority then explicitly set the priority:

function copyNodeStyle(sourceNode, targetNode) {
  const computedStyle = window.getComputedStyle(sourceNode);
  Array.from(computedStyle).forEach(
    key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), 'important')
  )
}
like image 22
Dragomir Denev Avatar answered Sep 21 '22 19:09

Dragomir Denev