Search code examples
javascriptcssfor-loopparent-childabstraction

How can I abstract this CSS-style-changing function


I'm trying to abstract a function.

This function loops over every child node of a given DOM element (passed into the function as an argument) and applies the same CSS style property & value to each one.

e.g.

function styleChildNodes(parent){

const children = parent.childNodes


for (let i = 0; i < children.length; i++) {

const child = children[i];




child.style.background = "red"


} }

In this example I have hard-coded the CSS property: background & its value as: "red" . The function will loop over every child node of the given parent element and change their CSS background properties to the color red.

But instead of having any hard-coded CSS property-value pair inside the function such as:

background = "red" , or, visibility = "hidden" , or, opacity = "1" , etc.

I want to pass in the desired CSS property and its value as arguments.

Here is an illustration of the concept:

function styleChildNodes(parent, property, value){

const children = parent.childNodes



for (let i = 0; i < children.length; i++) {

const child = children[i];




child.style.property = value


} }

The CSS property and its value could be anything I choose and I could use the function like this :

styleChildNodes(div, opacity, "0")

styleChildNodes(table, visibility, "hidden")

styleChildNodes(tr, background, "red")

styleChildNodes(div, height, "10px")

These are just pseudo-coded examples - but hopefully it conveys what I'm trying to achieve.

Any ideas, work-arounds, or non-eval() solutions are welcome!

Thank you for reading :-)

P.S. I hope I'm not misapplying "to abstract" when I say "I'm trying to abstract a function." Please let me know if I'm using imprecise terminology!

"Abstraction is a computer science concept in which an implementation is separated from its interface."


Solution

  • You can wrap property in brackets, but the property will need to be passed as a STRING so wrap it in quotes.

    function styleChildNodes(parent, property, value) {
      const children = parent.childNodes
      for (let i = 0; i < children.length; i++) {
        const child = children[i];
        child.style[property] = value
      }
    }
    

    you can also pass an object to do more than one:

    function styleChildNodes(parent, styles) {
      const children = parent.childNodes
      for (let i = 0; i < children.length; i++) {
        const child = children[i];
        child.style[property] = value
        for(style in styles){
            child.style[style] = styles[style]
       }
      }
    }
    
    styleChildNodes(parent, {
    "color": "red",
    "background-color": "green"
    })