Home > OS >  Why does my JS function only manipulate one <div> that is assigned to the class instead of all
Why does my JS function only manipulate one <div> that is assigned to the class instead of all

Time:01-18

I have this JS function that is supposed to initially hide a that has the class name "tw" and when clicked on a button it should make it visible. However, whenever I click the button it only changes the visibility of one div. I have 4. How can I fix this?

 function myFunction(){
      var elms = document.getElementsByClassName("tw");
     Array.from(elms).forEach((x) => {
        if (x.style.display === "block") {
          x.style.display = "none";
        } else {
          x.style.display = "block";
        }
      })
    }

https://jsfiddle.net/qm8bxryh/307/ Here's the fiddle

CodePudding user response:

I copied your code into the context of a very simple page (see below) and it seems to work...I might have missed something, but could the issue be elsewhere in your project? Perhaps investigating it piece by piece in the browser console could help.

<!DOCTYPE html>
<html>
    <script>
        function myFunction(){
      var elms = document.getElementsByClassName("tw");
     Array.from(elms).forEach((x) => {
        if (x.style.display === "block") {
          x.style.display = "none";
        } else {
          x.style.display = "block";
        }
      })
    }
    </script>
    <body>
        <button onclick="myFunction()">Click me</button>
        <div >1</div>
        <div  style="display: block;">2</div>
        <div >3</div>
        <div  style="display: block;">4</div>
    </body>
</html>

CodePudding user response:

There is no display value set as default, so when you try to access it on an element where you never used display in css or style it returns undefined or nothing

Thats why on the first button click nothing happens if no element has any display, then due to your function all of them get through the else display: block and on the second click the all toggle

What i like to do is creating a class like displayNone

so in css:

.displayNone{
     display:none;
}

then whenever you wanna make an element invisible give it this class and then when you click the button just remove the class and all elements become visible

so like this in your function:

function myFunction() {
            var elms = document.getElementsByClassName("tw");
            console.log(elms);
            console.log(Array.from(elms));
            Array.from(elms).forEach((x) => x.classList.remove('displayNone')); // just remove the class
        }

alternatively you can also use the classList.toggle('displayNone) so it switches between display none and its inital display

CodePudding user response:

I would keep styling in the CSS realm and toggle a class in JS to display the element. Also when you return a nodeList using querySelectorAll() it is in array form already.

Add a css class to the CSS:

.display {
  display: block;
}

Then your JS function could be a lot more streamlined with toggle()

let elms = document.querySelectorAll(".tw");
function myFunction() {
  elms.forEach(el =>  el.classList.toggle('display'))
}

JSFiddle

  •  Tags:  
  • Related