Developer
Developer

Reputation: 230

Running Java Script on multiple identical elements

I have written a function to display or not display the title of an element. My code works correctly. But only the first element reacts to my code and other elements don't react to my code. My codes are as follows:

let eye = document.querySelector(".box_icon");
let excerpt = document.querySelector(".title_box");

eye.addEventListener("click", function() {
  if (this.classList.contains("bi-play-circle-fill")) {
    this.classList = "bi bi-power box_icon";
    excerpt.style.display = "block";
  } else {
    this.classList = "bi bi-play-circle-fill box_icon";
    excerpt.style.display = "none"
  }
});
.box_main {
  display: flex;
  justify-content: space-around;
}

.box_mini {
  width: 250px;
  height: 200px;
  background: #5ec7ff;
  box-shadow: 0 0 4px #000;
}

.box_icon {
  font-size: 25px;
  margin: 10px 40% 6px;
  color: #7f7f7f;
}

.title_box {
  font-size: 45px;
  margin: 25px 15px 20px;
  color: #f9ff4d;
  display: none;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" />
<section class="box_main">
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

</section>

Please guide me to edit the java script code I wrote.

Upvotes: 0

Views: 85

Answers (2)

mplungjan
mplungjan

Reputation: 177950

Delegate and toggle

Alternative to title.hidden = !on; could be title.classList.toggle("show",on) if you want to use display:block/none classes

let container = document.querySelector(".box_main");
container.addEventListener("click", function(e) {
  const tgt = e.target;
  if (!tgt.matches('.box_icon')) return; // not the icon
  tgt.classList.toggle("bi-power");
  const title = tgt.closest('div.box_mini').querySelector('.title_box');
  const on = tgt.classList.contains("bi-power");
  title.hidden = !on;
});
.box_main {
  display: flex;
  justify-content: space-around;
}

.box_mini {
  width: 250px;
  height: 200px;
  background: #5ec7ff;
  box-shadow: 0 0 4px #000;
}

.box_icon {
  font-size: 25px;
  margin: 10px 40% 6px;
  color: #7f7f7f;
}

.title_box {
  font-size: 45px;
  margin: 25px 15px 20px;
  color: #f9ff4d;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" />
<section class="box_main">
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box" hidden>Title BOX</h1>
  </div>
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box" hidden>Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box" hidden>Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box" hidden>Title BOX</h1>
  </div>

</section>

Upvotes: 1

Trung Duong
Trung Duong

Reputation: 3475

You could use querySelectorAll, then loop on each matched element to add event listener.

Another method is to add event listener on container element, then check event's target element. If it's the box icon, we will hide/show corresponding elements.

document.querySelectorAll('.box_icon').forEach(eye => {
    eye.addEventListener("click", function() {
    let excerpt = this.parentNode.querySelector(".title_box");
    if (this.classList.contains("bi-play-circle-fill")) {
        this.classList = "bi bi-power box_icon";
        excerpt.style.display = "block";
    } else {
        this.classList = "bi bi-play-circle-fill box_icon";
        excerpt.style.display = "none"
      }
  });
});    
.box_main {
  display: flex;
  justify-content: space-around;
}

.box_mini {
  width: 250px;
  height: 200px;
  background: #5ec7ff;
  box-shadow: 0 0 4px #000;
}

.box_icon {
  font-size: 25px;
  margin: 10px 40% 6px;
  color: #7f7f7f;
}

.title_box {
  font-size: 45px;
  margin: 25px 15px 20px;
  color: #f9ff4d;
  display: none;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" />
<section class="box_main">
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

</section>

Upvotes: 0

Related Questions