Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getElementsByClassName doesn't work, but getElementById does? [duplicate]

I've written a script, it's goal is to stop displaying images one and two, while allowing image 3 to remain displayed and move into their place. It works fine when I use div Id's instead of div Classes, but I would prefer to use div classes so I can group the elements like this:

 function myFunction() {
     var y = document.getElementsByClassName("firstimage secondimage");
     if (y.style.display === 'none') {
           y.style.display = 'block';
     } else {
           y.style.display = 'none';
     }
 }

rather than this (in order to save space should I choose to include more elements):

 function myFunction() {
     var x = document.getElementById("firstimage");
     if (x.style.display === 'none') {
          x.style.display = 'block';
     } else {
          x.style.display = 'none';
     }

     var y = document.getElementById("secondimage");
     if (y.style.display === 'none') {
          y.style.display = 'block';
     } else {
          y.style.display = 'none';
     }
}

I thought that just changing the div id's to div classes, and the #imagenumber's to .imagenumber's (in addition to the change in the javascript I described above) would work but the script stops working when I do. I need the script to function in the same way that the code I am pasting below does, but with div classes instead of div Id's. Please tell me where I am going wrong.

CSS:

#firstimage {
    width: 100px;
    height: 100px;
    padding: 0px 0;
    text-align: center;
    background-color: green;
    margin-top:20px;
    color: white;
}

#secondimage {
    width: 100px;
    height: 100px;
    padding: 0px 0;
    text-align: center;
    background-color: blue;
    margin-top:20px;
    color: white;
}

#thirdimage {
    width: 100px;
    height: 100px;
    padding: 0px 0;
    text-align: center;
    background-color: red;
    margin-top:20px;
    color: white;
}

HTML:

<button onclick="myFunction()">Try me</button>

<div id="firstimage">
    DIV element.
</div>

<div id="secondimage">
    A second DIV element.
</div>

<div id="thirdimage">
    A third DIV element.
</div>

Javascript:

function myFunction() {
     var x = document.getElementById("firstimage");
     if (x.style.display === 'none') {
          x.style.display = 'block';
     } else {
          x.style.display = 'none';
     }

     var y = document.getElementById("secondimage");
     if (y.style.display === 'none') {
          y.style.display = 'block';
     } else {
          y.style.display = 'none';
     }
}
like image 481
Jack Elwell Avatar asked Aug 27 '16 06:08

Jack Elwell


2 Answers

document.getElementsByClassName returns an array of elements, so you would need to iterate through that array and operate on each element within that loop.

like image 189
Sterling Avatar answered Oct 27 '22 19:10

Sterling


You should use getElementsByClassName() or querySelectorAll() to collect all div.Klass (Klass being an arbitrary name). The following Snippet uses querySelectorAll() details are commented in source.

SNIPPET

function toggleDiv() {
  // Collect all .image into a NodeList
  var xs = document.querySelectorAll(".image");
  // Declare i and qty for "for" loop
  var i, qty = xs.length;
  // Use "for" loop to iterate through NodeList
  for (i = 0; i < qty; i++) {
    // If this div.image at index [i] is "none"...
    if (xs[i].style.display === 'none') {
      // then make it "block"... 
      xs[i].style.display = 'block';
    } else {
      // otherwise set display to "none"
      xs[i].style.display = 'none';
    }
  }
}
#firstimage {
  width: 100px;
  height: 100px;
  padding: 0px 0;
  text-align: center;
  background-color: green;
  margin-top: 20px;
  color: white;
}
#secondimage {
  width: 100px;
  height: 100px;
  padding: 0px 0;
  text-align: center;
  background-color: blue;
  margin-top: 20px;
  color: white;
}
#thirdimage {
  width: 100px;
  height: 100px;
  padding: 0px 0;
  text-align: center;
  background-color: red;
  margin-top: 20px;
  color: white;
}
<button onclick="toggleDiv()">Try me</button>

<div id="firstimage" class='image'>
  DIV element.
</div>

<div id="secondimage" class='image'>
  A second DIV element.
</div>

<div id="thirdimage" class='img'>
  A third DIV element.
</div>

In this function, just using an "array-like" object such as a NodeList demonstrated in the Snippet above. An array would be used in the same manner as it is in the Snippet. Should you want to do more advanced processing of the divs such as running a function on each of them and returned then converting an "array-like" object into an array would be necessary to run methods like map, forEach, slice, etc.

like image 30
zer00ne Avatar answered Oct 27 '22 18:10

zer00ne