I'm making a mini project for a coding class, featuring a list of poems. I set the poems in divs and the divs in a section (per a suggestion), and I want to toggle the poems' text and images so that they show or hide, and I wanted to change the button text to "Close" when shown from "Read" when hidden.
While I got some help, mainly with setting up the .forEach() method, I still can't find the solution. I've tried everything. Any other advice has been too confusing and too hard to follow.
Any help is appreciated. Thank you.
I tried using the different methods of retrieving elements from the DOM (.querySelector, .querySelectorAll, .getElementById, etc.). I tried changing the class and id names. I tried making it so I didn't shadow my variables. Literally everything.
let selection = document.querySelector(".poem")
const buttons = document.querySelectorAll(".btn");
// show poem or hide poem
// change text to "Read" or "Close"; if the poem is hidden, say "Read"; if it is showing, say "Close"
const readPoem = (poem) => {
if (selection.style.display == "none") {
selection.style.display = "block";
} else {
selection.style.display = "none";
}
};
console.log()
buttons.forEach((btn) => {
btn.addEventListener("click", (selection) => {
if (selection.style.display == "none") {
selection.style.display = "block";
btn.textContent = "Close";
} else {
selection.style.display = "none";
btn.textContent = "Read";
}
});
});
Based on your description, I assume that your HTML structure is like this:
<section>
<div class="poem-container">
<button class="btn">Read</button>
<div class="poem" style="display: none;">
<!-- Poem content here -->
</div>
</div>
<div class="poem-container">
<button class="btn">Read</button>
<div class="poem" style="display: none;">
<!-- Poem content here -->
</div>
</div>
<!-- More poem containers as needed -->
</section>
The event handler function accepts an Event
object. You are passing the selection
, which is not relevant.
Then we get the poem
that is in the same container as the button (they are both in the .poem-container
):
const poem = btn.closest(".poem-container").querySelector(".poem");
And finally, we can continue with the rest of the logic.
Here is the updated code and demo:
const buttons = document.querySelectorAll(".btn");
buttons.forEach((btn) => {
btn.addEventListener("click", (event) => {
// Find the associated poem div
const poem = btn.closest(".poem-container").querySelector(".poem");
if (poem.style.display === "none" || poem.style.display === "") {
poem.style.display = "block";
btn.textContent = "Close";
} else {
poem.style.display = "none";
btn.textContent = "Read";
}
});
});
.poem-container {
margin-bottom: 20px;
border: 1px solid black;
padding: 20px;
width: fit-content;
}
<section>
<div class="poem-container">
<button class="btn">Read</button>
<div class="poem" style="display: none;">
I am a poem
</div>
</div>
<div class="poem-container">
<button class="btn">Read</button>
<div class="poem" style="display: none;">
I am another poem
</div>
</div>
<!-- More poem containers as needed -->
</section>