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>

5
  • What behavior are you trying to achieve here? for (boxInternals of boxInternal) { is missing const so you're declaring a global. Commented Jul 23, 2021 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. Commented Jul 23, 2021 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? Commented Jul 23, 2021 at 22:52
  • I know bro, I'm not actually using it in a project but learning how to manipulate div. Commented Jul 23, 2021 at 23:14
  • Try always to use <button type="button" (by muscle-memory) since by default button type is "submit" - not super-necessary in that specific case but helps avoid issues on the long run. Commented Jul 24, 2021 at 0:05

1 Answer 1

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.

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

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.