Reputation: 39
I'm trying to make multiple popup buttons using the same javascript function. The is a 2x2 grid. The is a grid child. each grid child is intended to be a button. When the buttons are clicked, I want the content in between the corresponding divs (,) to display in this fashion: https://codepen.io/keaux/pen/zYGzENG
The HTML
<div class="container">
<div class="box" id="button1">
<a href="#" onclick="toggle()">HURRICANE TRACK</a>
</div>
<div id="popup1">
<h2>HURRICANE TRACKING</h2>
<video src="python_movies/hurricanetrack.mov"controls></video>
<p>
A Python project that prompts the user for a file containing hurricane information in order to form a dictionary that contains the names of hurricanes, the years the hurricanes occurred, and the correspoding data for each of the hurricanes, including the trajectory, longitude, lattitude, and wind speed. The program graphs all of the corresponding information by adding the information on a table, graphing the trajectory of the hurricanes, and plotting the information in a graph according to the wind speed.
</p>
<a href="#" onclick="toggle()">CLOSE</a>
</div>
<div class="box" id="button2">
<a href="#" onclick="toggle()">NINE MEN'S MORRIS</a>
</div>
<div id="popup2">
<h2>NINE MEN'S MORRIS</h2>
<video src="python_movies/ninemensmorris.mov"controls></video>
<p>
A Python Projects that runs the game, Nine Men's Morris. Nine Men's Morris is a two player game that combines elements of tic-tac-toe and checkers. The board consists of a grid with twenty-four intersections or points. Each player has nine pieces. Players try to form 'mills'—three of their own men lined horizontally or vertically—allowing a player to remove an opponent's man from the game. A player wins by reducing the opponent to two pieces (where they could no longer form mills and thus be unable to win), or by leaving them without a legal move. The game proceeds in three phases:
</p>
<ul>
<li>Placing pieces on vacant points</li>
<li>Moving pieces to adjacent points</li>
<li>(optional phase) Moving pieces to any vacant point when the player has been reduced to three men</li>
</ul>
<a href="#" onclick="toggle()">CLOSE</a>
</div>
I changed the Javascript to:
function toggle()
{
var button = document.querySelectorAll("#button1,#button2");
button.classList.toggle('active');
var popup = document.querySelectorAll("#popup1,#popup2");
popup.classList.toggle('active');
}
And now I get an error on the second line of my javascript that says:
popup.js:5 Uncaught TypeError: Cannot read property 'toggle' of undefined
at toggle (popup.js:5)
at HTMLAnchorElement.onclick (VM1916 codingprojects.html:20)
How do I fix this?
Upvotes: 1
Views: 104
Reputation: 4005
Use of classes is better for multiple elements:
document.querySelectorAll(".button a").forEach((a)=>{a.addEventListener("click",toggle);});
document.querySelectorAll(".popup a:last-child").forEach((a)=>{a.addEventListener("click",close);});
function toggle(){
this.parentElement.nextElementSibling.classList.toggle("active"); //popup is sibling of a's parent element
}
function close(){
this.parentElement.classList.toggle("active"); // .popup
}
.popup{
display: none;
}
.active{
display: block;
}
<div class="container">
<div class="box button">
<a href="#">HURRICANE TRACK</a>
</div>
<div class="popup">
<h2>HURRICANE TRACKING</h2>
<video src="python_movies/hurricanetrack.mov"controls></video>
<p>
A Python project that prompts the user for a file containing hurricane information in order to form a dictionary that contains the names of hurricanes, the years the hurricanes occurred, and the correspoding data for each of the hurricanes, including the trajectory, longitude, lattitude, and wind speed. The program graphs all of the corresponding information by adding the information on a table, graphing the trajectory of the hurricanes, and plotting the information in a graph according to the wind speed.
</p>
<a href="#">CLOSE</a>
</div>
<div class="box button">
<a href="#">NINE MEN'S MORRIS</a>
</div>
<div class="popup">
<h2>NINE MEN'S MORRIS</h2>
<video src="python_movies/ninemensmorris.mov"controls></video>
<p>
A Python Projects that runs the game, Nine Men's Morris. Nine Men's Morris is a two player game that combines elements of tic-tac-toe and checkers. The board consists of a grid with twenty-four intersections or points. Each player has nine pieces. Players try to form 'mills'—three of their own men lined horizontally or vertically—allowing a player to remove an opponent's man from the game. A player wins by reducing the opponent to two pieces (where they could no longer form mills and thus be unable to win), or by leaving them without a legal move. The game proceeds in three phases:
</p>
<ul>
<li>Placing pieces on vacant points</li>
<li>Moving pieces to adjacent points</li>
<li>(optional phase) Moving pieces to any vacant point when the player has been reduced to three men</li>
</ul>
<a href="#">CLOSE</a>
</div>
Upvotes: 0
Reputation: 413
querySelectorAll returns a list of nodes, so toggle is no longer available. You should iterate through each element you have in the list and call toggle. - same for popups. Example:
var buttons = document.querySelectorAll("#button1,#button2");
buttons.forEach(function(btn){ btn.classList.toggle('active'); });
Documentation - https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll see the examples provided.
Upvotes: 1