简体   繁体   中英

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

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

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 class="tw">1</div>
        <div class="tw" style="display: block;">2</div>
        <div class="tw">3</div>
        <div class="tw" style="display: block;">4</div>
    </body>
</html>

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM