user5833913
user5833913

Reputation:

Accessing multiple elements by getElementsByClassName() with JS

I am trying to create multiple popups on one page that would appear after clicking a button corresponding to them. I currently have them under the same class, as in here:

<div>
    <!-- Popup -->
        <div class="popup">
            <div class="popup-content">
                Some text here
            </div>
        </div>
    <!-- Button -->
    <img src="button.png" class="popup-button"/>
</div>

The problem is that I am struggling to access individual elements with my javascript code. I am not sure what to replace the manual array accessing ( [0] right now ) with.

<script>
// Get the popup
var popup = document.getElementsByClassName("popup")[0];

// Get the button that opens the popup
var btn = document.getElementsByClassName("popup-button")[0];

// When the user clicks the button, open the popup (hidden by default)
btn.onclick = function() {
    popup.style.display = "block";
}

</script>

Now, I could create multiple scripts and access the arrays manually for each element but of course I am trying to automate it, so that script would run depending on which button was clicked. Say, if 5th button was clicked, 5th popup appears. Thank you!

Upvotes: 0

Views: 1959

Answers (4)

Takit Isy
Takit Isy

Reputation: 10081

Depending on your HTML structure, there are multiple possibilities.

Anyway, I suggest you to use .querySelectorAll() to get your elements, and then use a .forEach() to execute your code.

I tried to use much of your code to make it work correctly.

With a parent div

// Get all the buttons that opens the popups
var btns = document.querySelectorAll(".popup-button");

btns.forEach(function(btn, index) {
  // When the user clicks the button, open the popup that is in the same parent div
  btn.onclick = function() {
    btn.closest('div').querySelector('.popup').style.display = "block";
  }
});
.popup {
  display: none;
}
<div>
  <div class="popup">
    <div class="popup-content">Pop-up 1</div>
  </div>
  <img src="button.png" class="popup-button" />1
</div>

<div>
  <div class="popup">
    <div class="popup-content">Pop-up 2</div>
  </div>
  <img src="button.png" class="popup-button" />2
</div>

<div>
  <div class="popup">
    <div class="popup-content">Pop-up 3</div>
  </div>
  <img src="button.png" class="popup-button" />3
</div>


Without a parent div

// Get the popups
var popups = document.querySelectorAll(".popup");
// Get the buttons that opens the popups
var btns = document.querySelectorAll(".popup-button");

btns.forEach(function(btn, index) {
  // When the user clicks the button, open the popup (hidden by default)
  btn.onclick = function() {
    popups[index].style.display = "block";
  }
});
.popup {
  display: none;
}
<div class="popup">
  <div class="popup-content">Pop-up 1</div>
</div>
<img src="button.png" class="popup-button" />
<br>
<br>
<div class="popup">
  <div class="popup-content">Pop-up 2</div>
</div>
<img src="button.png" class="popup-button" />
<br>
<br>
<div class="popup">
  <div class="popup-content">Pop-up 3</div>
</div>
<img src="button.png" class="popup-button" />

This solution withour parent div will work even if the popups and the buttons are not next to each other. But the order (and index) of the elements need to be the same. See it here:

// Get the popups
var popups = document.querySelectorAll(".popup");
// Get the buttons that opens the popups
var btns = document.querySelectorAll(".popup-button");

btns.forEach(function(btn, index) {
  // When the user clicks the button, open the popup (hidden by default)
  btn.onclick = function() {
    popups[index].style.display = "block";
  }
});
.popup {
  display: none;
}
<img src="button.png" class="popup-button" />1
<img src="button.png" class="popup-button" />2
<img src="button.png" class="popup-button" />3

<div class="popup">
  <div class="popup-content">Pop-up 1</div>
</div>
<div class="popup">
  <div class="popup-content">Pop-up 2</div>
</div>
<div class="popup">
  <div class="popup-content">Pop-up 3</div>
</div>

Hope it helps.

Upvotes: 0

robinvrd
robinvrd

Reputation: 1848

Best way to link multiple elements in Javascript is using an id through the dataset of the elements.

// Get the popup's btn list
var popupsBtn = document.getElementsByClassName("popup-btn");

// Go through the popup's btn list
for (var i = 0; i < popupsBtn.length; i++) {
  
  // Define the onclick event on popup's btn
  popupsBtn[i].onclick = function() {
  
    // Get the popup associated to the btn with the data-popup-id
    var popup = document.getElementById("popup-" + this.dataset.popupId);
    
    // Use a class to toggle popup visible or not
    popup.classList.toggle("visible");
    
  }
  
}
.popup {
  display: none;
}

.popup.visible {
  display: block;
}
<!DOCUMENT html>
<html>
  <head></head>
  <body>
    <div>
      <div id="popup-1" class="popup">popup 1 here</div>
      <img src="button.png" class="popup-btn" data-popup-id="1" />
    </div>
    <div>
      <div id="popup-2" class="popup">popup 2 here</div>
      <img src="button.png" class="popup-btn" data-popup-id="2" />
    </div>
    <div>
      <div id="popup-3" class="popup">popup 3 here</div>
      <img src="button.png" class="popup-btn" data-popup-id="3" />
    </div>
  </body>
</html>

Upvotes: 1

Ranielle Canlas
Ranielle Canlas

Reputation: 634

You can use other attributes to identify the button. You could not rely on the className alone. You can use data-id attribute and pass it in the method. using this.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370679

Given your HTML, it would probably be easiest to just access the previous sibling of the clicked button to get to the .popup, and then change its style:

document.querySelectorAll('.popup-button').forEach(button => {
  button.onclick = () => {
    button.previousElementSibling.style.display = 'block';
  };
});
.popup {
  display: none;
}
<div>
  <div class="popup">
    <div class="popup-content">
      Some text here1
    </div>
  </div>
  <img src="button.png" class="popup-button" />
</div>
<div>
  <div class="popup">
    <div class="popup-content">
      Some text here2
    </div>
  </div>
  <img src="button.png" class="popup-button" />
</div>
<div>
  <div class="popup">
    <div class="popup-content">
      Some text here3
    </div>
  </div>
  <img src="button.png" class="popup-button" />
</div>

Upvotes: 1

Related Questions