1

I know how to select similarly named class name or ID if there are in the same direct parent, meaning if there are in the same box, proof https://codepen.io/akpobi/pen/poPddMr. But if there are more boxes and I'm trying to target all the buttons in their separate parents, it doesn't work. Help.

const btn = document.querySelector(".btn");
const box = document.querySelector(".box");

const boxInternal = document.querySelector(".box-internal").childNodes;

const popFunc = function(event) {
  for (const boxInternals of boxInternal) {
    if (event.target == boxInternals) {
      box.classList.toggle("box-scale");
    }
  }
};

btn.addEventListener("click", popFunc, false)
<div class="box-wrapper">
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
</div>
ggorlen
  • 44,755
  • 7
  • 76
  • 106
jstn
  • 11
  • 3
  • What behavior are you trying to achieve here? `for (boxInternals of boxInternal) {` is missing `const` so you're declaring a global. – ggorlen Jul 23 '21 at 22:38
  • Well, true but I don't think it's actually that important in this snippet of what I'm trying to achieve. I can't verbally explain what I'm trying to achieve that well. Let's say there's more button in that "box-internal" class, I can select all of them but if the second box div have buttons too, I can't select them. – jstn Jul 23 '21 at 22:51
  • 1
    No, but it might cause problems in your app later so you might as well fix it. `popFunc` is also global, and `===` is preferred over `==`. What should happen to the boxes when you click a button? – ggorlen Jul 23 '21 at 22:52
  • I know bro, I'm not actually using it in a project but learning how to manipulate div. – jstn Jul 23 '21 at 23:14
  • Try always to use ` – Roko C. Buljan Jul 24 '21 at 00:05

1 Answers1

1

You can use .closest(".box") to get the closest enclosing box to the event target, then toggle the desired class on it:

for (const btn of document.querySelectorAll(".btn")) {
  btn.addEventListener("click", evt => {
    evt.target.closest(".box").classList.toggle("box-scale");
  });
}
body {
  background-color: #0a0a16;
  color: #ffffff;
  margin: auto;
}

.box-wrapper {
  display: flex;
  position: fixed;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
}

.box {
  width: 200px;
  height: 120px;
  background-color: rgb(18, 18, 37);
  margin: 5px;
  transition: 0.6s;
}

.box-scale {
  transform: scale(1.4);
}
<div class="box-wrapper">
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
</div>

Alternatively, you can use event delegation in the parent element:

document.querySelector(".box-wrapper")
  .addEventListener("click", ({target: el}) => {
    el.closest(".btn")
     ?.closest(".box")
     ?.classList
      .toggle("box-scale")
    ;
  })
;
body {
  background-color: #0a0a16;
  color: #ffffff;
  margin: auto;
}

.box-wrapper {
  display: flex;
  position: fixed;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
}

.box {
  width: 200px;
  height: 120px;
  background-color: rgb(18, 18, 37);
  margin: 5px;
  transition: 0.6s;
}

.box-scale {
  transform: scale(1.4);
}
<div class="box-wrapper">
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
  <div class="box">
    <div class="box-internal">
      <button class="btn">Click</button>
    </div>
  </div>
</div>

If this is part of a form, you might want to disable submit with type="button" attributes on your buttons.

ggorlen
  • 44,755
  • 7
  • 76
  • 106