0

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.

5
  • There is no jQuery in your code. Also there is no need for it Commented Feb 12, 2023 at 11:36
  • You need querySelectorAll instead of querySelector Commented Feb 12, 2023 at 11:42
  • Hello. I corrected the question. Is there a way to solve this problem or not? Commented Feb 12, 2023 at 11:45
  • 1
    As stated you will need querySelectorAll(). The returned elements will be stored in the form of an array. So to add an event listener to all of them, you'll need to loop over them. I.e. use a .forEach or in your case just a for loop, so you can also reference the .excerpt elements that you want to style by their index (i.e. excerpt[i]). Commented Feb 12, 2023 at 12:08
  • Hello. I used querySelectorAll() but it didn't work. Can you edit my script code? Commented Feb 12, 2023 at 12:12

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

2 Comments

Your code does not run correctly. If you click on the box instead of the icon, it gives an error. Can you edit the simple code I wrote?
@Developer You are correct. I missed the test if (!tgt.matches('.box_icon')) return; - I strongly recommend using my version instead of your non-working simple code or the accepted answer which adds an event listener to every single icon.
0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.