Having trouble with toggling

I am currently doing a project for a class, and I want to make it so the div elements with toggle their display. So far, I’ve only gotten the first div to toggle properly, while the rest do nothing.

Here is my code:

const selection = document.querySelectorAll("#poem-selection");
const readBtn = document.getElementById("read-btn");

const readPoem = (selection) => {
  selection.style.display = "block";
  readBtn.textContent = "Close";
};

const closePoem = (selection) => {
  selection.style.display = "none";
  readBtn.textContent = "Read";
};

readBtn.addEventListener("click", (selection) => {
  if (readBtn.textContent === "Read") {
    readPoem(selection);
  } else if (readBtn.textContent === "Close") {
    closePoem(selection);
  }
});

Also, it keeps throwing the error “cannot set properties of undefined (setting ‘display’).” But everything matches!

Any help is appreciated! Thanks.

Here is my HTML :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Welcome to my poetry page!</title>
    <link rel="stylesheet" href="styles.css" />
    <link rel="stylesheet" href="https://use.typekit.net/oez5blv.css" />
    <link
      rel="stylesheet"
      href="https://use.fontawesome.com/releases/v5.8.2/css/all.css"
    />
  </head>
  <body>
    <header>
      <div id="name-box">
        <h1 id="title">Airen's Poetry Page</h1>
      </div>
      <nav id="header-navbar">
        <ul>
          <li><a href="index.html">Poems</a></li>
          <li><a href="about.html">About Me</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1 id="welcome">Welcome to my poetry page!</h1>
      <h2>
        Below are five of my favorite poems. Click "Read" next to each title.<br /><br />Thanks
        for reading!
      </h2>
      <h3 class="poem-title">
        Apiphobia/Spheksophobia
        <button class="read-btn" id="read-btn">Read</button>
      </h3>
      <div id="poem-selection">
        <img
          class="cover-photo"
          src="/images/bees.jpg"
          alt="Thorns. Thorns everywhere."
        />
        <p>
          Every summer, the trees have thorns.<br />
          The grass and flowers and bushes have thorns.<br />
          The brick-wall buildings, the warm concrete,<br />
          That mud puddle by the construction site—<br />
          All these things have thorns.<br />
          A bottle of soda left out to bake<br />
          May have a thorn or two.<br />
          I think I’ve even seen a few<br />
          Protruding from a chicken bone<br />
          Peeking out of a garbage can.<br />
          A thorn here, a thorn there.<br />
          Thousands of them float around in the air!<br />
          On the window, on the wall—<br />
          There’s even thorns inside.<br />
          I’ve got nowhere to hide!<br />
          Every place is a potential prick;<br />
          Even the soft clouds above have thorns.<br />
          Even the invisible stars of day!<br />
          Everything, everyone, everywhere—<br />
          All I see are thorns.<br /><br />
          <i>(2011; rev. 2024)</i>
        </p>
      </div>
      <h3 class="poem-title">
        Awakening
        <button class="read-btn" id="read-btn">Read</button>
      </h3>
      <div id="poem-selection">
        <img
          class="cover-photo"
          src="/images/supernova.jpg"
          alt="The awakening."
        />
        <p>
          What is this? It appears<br />
          the sky can't hold itself together;<br />
          the sun's bleeding red and the<br />
          clouds are on fire---<br />
          inferno everywhere.<br /><br />

          Cracks in the sky's blue<br />
          reveal the black of space;<br />
          through this I see the planets<br />
          aligning, as the stars around them<br />
          collapse into a collective nova.<br /><br />

          The moon absorbs the sun's blood<br />
          like a celestial gauze.<br />
          Back home, I look up and<br />
          could swear I see a flock of pigs<br />
          flying over the Ohio---<br /><br />

          and no one sees this but me;<br />
          any who had would surely have thought<br />
          that our world was ending,<br />
          but I know the truth:<br />
          It is but the beginning.<br /><br />

          <i>(2011; rev. 2016)</i>
        </p>
      </div>
      <h3 class="poem-title">
        Keys
        <button class="read-btn" id="read-btn">Read</button>
      </h3>
      <div id="poem-selection">
        <img class="cover-photo" src="/images/keys.jpg" alt="Lots of keys." />
        <p>
          While window shopping at the mall<br />
          I stop by a jewelry display case<br />
          Where something catches my attention――<br /><br />

          It is a set of silver keys.<br />
          Shiny, beautiful little keys.<br />
          I am obsessed by these keys.<br /><br />

          I don’t know why, but I like keys.<br />
          Lately there’s been something about them…<br />
          Something that gives them importance.<br /><br />

          I guess it’s what they signify.<br />
          Keys, to most, mean access―<br />
          A way in, a way out.<br /><br />

          With keys we open many things――<br />
          Locks, doors, chests and drawers;<br />
          Hearts, souls, our wildest dreams.<br /><br />

          Keys can also set us free――<br />
          From prison cells and rusty cages;<br />
          From the confines of our own madness.<br /><br />

          Maybe I’m seeking access to something―<br />
          Something that’s been denied me for years,<br />
          Or something I myself have denied.<br /><br />

          Or maybe I long to escape,<br />
          To break away and be free…<br />
          Or, perhaps, to set something free.<br /><br />

          Whatever my desire, here I stand,<br />
          Admiring these trinkets and their sparkle,<br />
          Thinking to myself,<br /><br />

          <em>Gotta have one, one of those keys.</em><br />
          But my money isn’t enough. See?—<br />
          I need a way out. I need access.<br /><br />

          <i>(2011)</i>
        </p>
      </div>
      <h3 class="poem-title">
        Leviathan
        <button class="read-btn" id="read-btn">Read</button>
      </h3>
      <div id="poem-selection">
        <img
          class="cover-photo"
          src="/images/leviathan.jpg"
          alt="The legendary demon of envy."
        />
        <p>
          Emerging, I,<br />
          from the depths once more,<br />
          I seek out my prey--<br /><br />

          those whose hearts<br />
          fester with contempt<br />
          for the joy of others,<br /><br />

          who scowl with disdain<br />
          for the merge of souls<br />
          of which they are not one,<br /><br />

          yet also mourn<br />
          for years long past and <br />
          opportunities wasted.<br /><br />

          Their selfish yearning,<br />
          their misplaced determination,<br />
          is what sustains me.<br /><br />

          Such is the case<br />
          with one repeat offender--<br />
          she reappears<br /><br />

          in these volatile waters,<br />
          aboard her dismal vessel<br />
          of past regret, with<br /><br />

          winds of desperation<br />
          blowing into its sails,<br />
          driving it forward<br /><br />

          with no planned destination.<br />
          She sails for opportunity, for<br />
          what she assumes is lost.<br /><br />

          Along the sea's horizon,<br />
          beyond the storms of chaos,<br />
          where daylight has cut through,<br /><br />

          she spots a couple<br />
          coming of age--one stands in light;<br />
          his partner, his shadow.<br /><br />

          They travel the world--<br />
          he illuminates, while she filters,<br />
          lest his own light blind him.<br /><br />

          Such juxtaposition appears<br />
          to bring its witness to despair,<br />
          for she cannot partake.<br /><br />

          For years, she has longed<br />
          for such a love,<br />
          for such a light; yet<br /><br />

          she always reached for it<br />
          with cold, wet hands,<br />
          exploding the bulbs in her face.<br /><br />

          This made her a risk.<br />
          Alone and afraid,<br />
          she keeps a distance,<br /><br />

          watching, waiting, wishing,<br />
          dreaming, coveting,<br />
          hoping against hope----<br /><br />

          I lie in wait, ready to strike,<br />
          ready to feed, as I have<br />
          many a time before,<br /><br />

          when this desperate soul<br />
          has respawned, reemerged,<br />
          to make the same mistake.<br /><br />

          Yet this time around,<br />
          I hesitate, then resign,<br />
          unwilling to attack.<br /><br />

          It seems she is changing--<br />
          still grappling, yet willing<br />
          to abandon her voyage,<br /><br />

          to sail into the sun<br />
          and bask in its warmth,<br />
          out of the darkness,<br /><br />

          out of my reach.<br />
          Her inspiration comes<br />
          from the lovers--<br /><br />

          the light's radiating glow,<br />
          touching all who see it,<br />
          is inviting and warm;<br /><br />

          its contagion spreads<br />
          across a great distance,<br />
          even reaching me.<br /><br />

          His shadow absorbs it, too,<br />
          her own obscure light<br />
          enhanced manyfold----<br /><br />

          and the witness,<br />
          the lonely traveler<br />
          reappearing all these years,<br /><br />

          begins herself to beam,<br />
          standing tall,<br />
          holding her head high,<br /><br />

          ignited by the same light<br />
          which moments before<br />
          nearly deepened her misery.<br /><br />

          But I know that<br />
          this light that radiates<br />
          is not merely spreading,<br /><br />

          but rather activating--<br />
          all who shine it forth<br />
          are themselves the source.<br /><br />

          This light is love--<br />
          the universal kind,<br />
          that which created all.<br /><br />

          It fills the sails<br />
          that carry my sailor,<br />
          pushing toward the sun;<br /><br />

          she casts regrets and envy aside,<br />
          drifting away from despair,<br />
          escaping my grasp.<br /><br />

          Not often am I denied,<br />
          as all humans do err.<br />
          Still, there comes a time<br /><br />

          for everything--even<br />
          to tame this ancient reaper,<br />
          this eater of sin.<br /><br />

          I retreat into the deep,<br />
          deprived, but not bitter--<br />
          I know there are others.<br /><br />
          <i>(2017)</i>
        </p>
      </div>
      <h3 class="poem-title">
        September
        <button class="read-btn" id="read-btn">Read</button>
      </h3>
      <div id="poem-selection">
        <img
          class="cover-photo"
          src="/images/leaves.jpg"
          alt="The colors of fall."
        />
        <p>
          All around me<br />
          I feel the season turning--<br /><br />

          even as the heat rages on<br />
          and storms parade through the skies,<br /><br />

          as foliage retains its green<br />
          in leaves that dance in the breeze;<br /><br />

          as bees thirst on for sweet nectar,<br />
          and mosquitoes, for tender veins,<br /><br />

          as crickets chirp deep in the grass<br />
          and cicadas chatter across treetops.<br /><br />

          I see al fresco diners sip cocktails<br />
          and restless children play,<br /><br />

          hear the gurgle of fountains<br />
          and the hum of A/Cs,<br /><br />

          feel the heat in the pavement<br />
          warm the soles of my shoes---<br /><br />

          yet I still sense the change,<br />
          the approaching front,<br /><br />

          come to coax all to rest<br />
          in advent of the new.<br /><br />
          <i>(2016)</i>
        </p>
      </div>
    </main>
    <footer>
      <div id="find-me">
        <h3>You can find my stuff here:</h3>
      </div>
      <nav id="footer-navbar">
        <ul>
          <li>
            <a
              id="profile-link"
              href="https://github.com/AirenMarie"
              target="_blank"
              ><i class="fab fa-github"></i
            ></a>
          </li>
          <li>
            <a
              id="profile-link"
              href="https://codepen.io/airenmarie"
              target="_blank"
              ><i class="fab fa-codepen"></i
            ></a>
          </li>
        </ul>
      </nav>
    </footer>
    <script src="script.js"></script>
  </body>
</html>

And here’s my CSS:

body {
  font-family: "edita", serif;
  background-image: url(/images/red_background.jpg);
  background-color: black;
  color: #f9c3d8;
}

header {
  width: 100%;
  height: 125px;
  display: flex;
  flex-wrap: nowrap;
  white-space: nowrap;
  justify-content: space-evenly;
  align-items: center;
  position: fixed;
  top: 0;
  background-color: #490005;
}

#name-box {
  width: 50%;
  min-width: 400px;
  max-height: 200px;
  margin-left: -50px;
  margin-right: -30px;
  text-align: center;
  position: fixed;
  left: 0;
}

#title {
  font-size: 2.7rem;
}

#header-navbar {
  width: 50%;
  min-width: 400px;
  height: 50px;
  max-height: 50px;
  margin: 30px -50px 25px 100px;
  float: right;
  position: relative;
  top: 0;
  left: 5%;
  right: 7%;
}

#header-navbar > ul {
  display: flex;
  justify-content: space-evenly;
  flex-wrap: wrap;
  white-space: wrap;
  align-items: center;
  padding-inline-start: 0;
  margin-block: 0;
  height: 100%;
}

#header-navbar li {
  list-style: none;
  margin: 0 0.5rem;
  padding: 0.2rem;
  display: block;
}

#header-navbar a {
  text-decoration: none;
  font-size: 1.9rem;
  font-weight: 600;
  color: #f9c3d8;
}

#header-navbar a:hover {
  color: #fffafe;
  cursor: pointer;
}

main {
  margin-top: 150px;
}

#welcome,
#about {
  font-size: 4rem;
  text-align: center;
}

h2 {
  font-size: 2.2rem;
  text-align: center;
  margin: 50px 0 50px 0;
}

#poem-selection {
  margin: 50px 150px 50px 150px;
  display: none;
}

#poem-selection:last-of-type {
  margin-bottom: 200px;
}

.poem-title {
  margin-left: 150px;
}

.poem-title,
#poem-selection p {
  font-size: 2rem;
}

#bio {
  font-size: 1.8rem;
  margin: 0 150px 200px 150px;
}

#poetry {
  color: #f9c3d8;
}

#poetry:hover {
  color: #fffafe;
}

.read-btn {
  font-size: 1.7rem;
  font-family: "edita", serif;
  font-weight: 700;
  text-align: center;
  border: 0;
  background: none;
  color: #f9c3d8;
  padding: 0 10px 0 10px;
  margin-left: 30px;
}

.read-btn:hover {
  color: #fffafe;
  border: 1px solid #fffafe;
  cursor: pointer;
}

.cover-photo {
  max-width: 1000px;
  display: block;
}

#bio-pic {
  max-width: 600px;
  display: block;
  margin: 0 auto;
}

footer {
  width: 100%;
  height: 125px;
  display: flex;
  flex-wrap: nowrap;
  white-space: nowrap;
  justify-content: space-evenly;
  align-items: center;
  position: fixed;
  bottom: 0;
  background-color: #490005;
}

#find-me {
  width: 50%;
  min-width: 400px;
  max-height: 200px;
  margin: 0 30px 0 -80px;
  text-align: center;
  position: fixed;
  left: 5%;
  right: 5%;
  font-size: 2.3rem;
}

#footer-navbar {
  width: 50%;
  min-width: 400px;
  height: 50px;
  max-height: 50px;
  margin: 25px -200px 30px -20px;
  float: right;
  position: relative;
  bottom: 0;
  left: 5%;
  right: 7%;
}

#footer-navbar > ul {
  display: flex;
  justify-content: space-evenly;
  flex-wrap: wrap;
  white-space: wrap;
  align-items: center;
  padding-inline-start: 0;
  margin-block: 0;
  height: 100%;
}

#footer-navbar li {
  list-style: none;
  margin: 0 0.5rem;
  padding: 0.2rem;
  display: block;
}

#profile-link {
  text-decoration: none;
  font-size: 1.5rem;
  font-weight: 600;
  color: #f9c3d8;
}

#profile-link:hover {
  color: #fffafe;
  cursor: pointer;
}

.fab {
  font-size: 4rem;
}

This is why you are seeing the error.
You cannot set a display on something that is not an Element. (This selection is a NodeList which is an array like object).

Okay.

So, I need to create new variables in the functions…right?..

I didn’t understand your follow up question? Are we still on the subject of the error?

Oh, sorry.

Yes, I was talking about declaring variables to fix the error.

Your functions are event handlers, so the selection parameter is the event object, not the elements you get from querySelectorAll.

It is important you know that when you name two identifiers (variable name) the same, the one that is closest to the scope it is used in wins. Technically, what you are doing is shadowing variables. You pretty much never want to do that. Your parameters should not be named the same as outer variables. It is just confusing to read.


  1. Group the elements inside a parent container.

  2. Inside the event handler, you can get to the click target using the .target property on the event.

  3. Now, traverse the DOM using nextElementSibling and get the poem element.

  4. Toggle a class on it to show/hide it.

  5. Set the button text using the button (the click target) text as the condition.


Example, I copied just the same poem for all three, it is just a quick example.

Summary
<section class="poems">
  <h3 class="poem-title">Apiphobia/Spheksophobia</h3>
  <button class="read-btn" id="read-btn">Read</button>
  <div class="poem">
    <img class="cover-photo" src="/images/bees.jpg" alt="Thorns. Thorns everywhere." />
    <p>
      Every summer, the trees have thorns.<br />
      The grass and flowers and bushes have thorns.<br />
      The brick-wall buildings, the warm concrete,<br />
      That mud puddle by the construction site—<br />
      All these things have thorns.<br />
      A bottle of soda left out to bake<br />
      May have a thorn or two.<br />
      I think I’ve even seen a few<br />
      Protruding from a chicken bone<br />
      Peeking out of a garbage can.<br />
      A thorn here, a thorn there.<br />
      Thousands of them float around in the air!<br />
      On the window, on the wall—<br />
      There’s even thorns inside.<br />
      I’ve got nowhere to hide!<br />
      Every place is a potential prick;<br />
      Even the soft clouds above have thorns.<br />
      Even the invisible stars of day!<br />
      Everything, everyone, everywhere—<br />
      All I see are thorns.<br /><br />
      <i>(2011; rev. 2024)</i>
    </p>
  </div>
</section>

<section class="poems">
  <h3 class="poem-title">Apiphobia/Spheksophobia</h3>
  <button class="read-btn" id="read-btn">Read</button>
  <div class="poem">
    <img class="cover-photo" src="/images/bees.jpg" alt="Thorns. Thorns everywhere." />
    <p>
      Every summer, the trees have thorns.<br />
      The grass and flowers and bushes have thorns.<br />
      The brick-wall buildings, the warm concrete,<br />
      That mud puddle by the construction site—<br />
      All these things have thorns.<br />
      A bottle of soda left out to bake<br />
      May have a thorn or two.<br />
      I think I’ve even seen a few<br />
      Protruding from a chicken bone<br />
      Peeking out of a garbage can.<br />
      A thorn here, a thorn there.<br />
      Thousands of them float around in the air!<br />
      On the window, on the wall—<br />
      There’s even thorns inside.<br />
      I’ve got nowhere to hide!<br />
      Every place is a potential prick;<br />
      Even the soft clouds above have thorns.<br />
      Even the invisible stars of day!<br />
      Everything, everyone, everywhere—<br />
      All I see are thorns.<br /><br />
      <i>(2011; rev. 2024)</i>
    </p>
  </div>
</section>

<section class="poems">
  <h3 class="poem-title">Apiphobia/Spheksophobia</h3>
  <button class="read-btn" id="read-btn">Read</button>
  <div class="poem">
    <img class="cover-photo" src="/images/bees.jpg" alt="Thorns. Thorns everywhere." />
    <p>
      Every summer, the trees have thorns.<br />
      The grass and flowers and bushes have thorns.<br />
      The brick-wall buildings, the warm concrete,<br />
      That mud puddle by the construction site—<br />
      All these things have thorns.<br />
      A bottle of soda left out to bake<br />
      May have a thorn or two.<br />
      I think I’ve even seen a few<br />
      Protruding from a chicken bone<br />
      Peeking out of a garbage can.<br />
      A thorn here, a thorn there.<br />
      Thousands of them float around in the air!<br />
      On the window, on the wall—<br />
      There’s even thorns inside.<br />
      I’ve got nowhere to hide!<br />
      Every place is a potential prick;<br />
      Even the soft clouds above have thorns.<br />
      Even the invisible stars of day!<br />
      Everything, everyone, everywhere—<br />
      All I see are thorns.<br /><br />
      <i>(2011; rev. 2024)</i>
    </p>
  </div>
</section>
.poems {
  display: flex;
}

.poem {
  display: none;
}

.show {
  display: block;
}
// all the buttons in a NodeList
const readBtns = document.querySelectorAll(".read-btn");

// Single event handler
const togglePoem = (event) => {
  // the event.target is the button that was clicked
  console.log(event.target);
  
  // the next sibling element after the button is the poem
  // Toggle the show class
  event.target.nextElementSibling.classList.toggle('show');
  
  // if the button text is Close set it to Read, otherwise, set it to Close
  readBtn.textContent = readBtn.textContent === "Close" ? "Read" : "Close";
};

// Loop the buttons and add the event listener
readBtns.forEach((btn) => {
  btn.addEventListener("click", togglePoem);
});

What do you mean by .target in the event handler?..

You replied to yourself, so I wasn’t notified of your question.



<button>Target test</button>
<p></p>
document.querySelector("button").addEventListener("click", (evt) => {
  evt.target.nextElementSibling.innerText = evt.target.innerText;
});

Here is what I’ve tried so far, after talking over with my class and getting there input.

let selections = document.querySelectorAll("#poem-selection")
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 (poem.style.display == "none") {
    poem.style.display = "block";
  } else {
    poem.style.display = "none";
  }
};

buttons.forEach((btn) => {
  btn.addEventListener("click", () => {
    let poem = selections;
    if (poem.style.display == "none") {
      poem.style.display = "block";
      btn.textContent = "Close";
    } else {
      poem.style.display = "none";
      btn.textContent = "Read";
    }
  });
});

Of course, I’m still getting errors.

I tried .target and .nextElementSibling and neither of those worked. They’re too confusing anyway.

I feel like just giving up… :disappointed:

  1. Don’t use querySelectorAll with ids. Ids are meant to be unique, you should not have the same id on more than one element.

  2. querySelectorAll returns a NodeList, so your selections is a NodeList. It works like an array and will contain all the elements that matched the selector. A Nodelist must be looped just as you are doing it with the buttons. You can manually index in to it as well but you will rarely do that. If you need a single element use querySelector.

  3. The event.target is the element that triggered the event. So for a button it would be the button. This makes it so you can use the target to identify which element triggered the event. If you have 4 buttons, and you click one of them, event.target will be the exact button that was clicked.

  4. nextElementSibling is simply the next element, so event.target.nextElementSibling is the element that comes after the element that fired the event. Using this setup as long as your poem comes after the button it will be the nextElementSibling.

Same setup as before:

<section>
  <button>Toggle Poem 1 visibility</button>
  <p>Poem 1</p>
</section>

<section>
  <button>Toggle Poem 2 visibility</button>
  <p>Poem 2</p>
</section>

<section>
  <button>Toggle Poem 3 visibility</button>
  <p>Poem 3</p>
</section>
document.querySelectorAll("button").forEach((btn) => {
  btn.addEventListener("click", (evt) => {
    // evt.target is the button that was clicked
    const button = evt.target;
    console.log(button);

    // button.nextElementSibling is the paragraph after the button
    const poem = button.nextElementSibling;
    console.log(poem);

    poem.style.display = poem.style.display === "none" ? "block" : "none";
  });
});

I would suggest you go through the curriculum. You can skip to the Role Playing Game to get into DOM manipulation.