-1

hello i have some nested divs. i want to know the index of div, which has class "row". when button is clicked i want to get div (class "raw" ) index of respected button. these div ( class raw ) are created by for loop so eventListener is not working.

<div class="container">
     <div class="row">
        <button>Click</button>
     </div>
      <div class="row">
        <button>Click</button>
     </div>
      <div class="row">
        <button>Click</button>
     </div>
</div>

please help me

gaurav joshi
  • 77
  • 1
  • 8
  • There are no elements with a `raw` class – Andreas Aug 26 '22 at 09:48
  • What have you done so far to solve this on your own? – Andreas Aug 26 '22 at 09:48
  • _"...are created by for loop so eventListener is not working."_ - Why shouldn't that work? -> [mcve] – Andreas Aug 26 '22 at 09:50
  • Actually a dupe of: [JavaScript DOM: Find Element Index In Container](https://stackoverflow.com/questions/11761881/javascript-dom-find-element-index-in-container) – Andreas Aug 26 '22 at 10:04
  • i tried this https://stackoverflow.com/questions/66771371/how-to-get-index-of-div-in-parent-div . but its not working because this divs ( class raw ) are created by loop after the page load that's why it cant read value of parent and child variables because it is not present in the page at load time – gaurav joshi Aug 26 '22 at 10:18
  • _"i cant use addEventListener"_ - Forget that flawed assumption. You can execute JavaScript when ever you want. Even when the elements aren't in the DOM yet you can already add an event listener on a parent element - or just wait until the elements are in the DOM -> [Introduction to events - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events) – Andreas Aug 26 '22 at 11:16
  • @gauravjoshi check this: https://stackoverflow.com/a/70455549/17716837 I was having the same problem before, and this answer solves that. – Laaouatni Anas Aug 26 '22 at 11:43
  • maybe use defer attribute in script tag, or put the script tag in the end – Laaouatni Anas Aug 26 '22 at 12:14
  • Does this answer your question? [JavaScript DOM: Find Element Index In Container](https://stackoverflow.com/questions/11761881/javascript-dom-find-element-index-in-container) – Erik Aug 28 '22 at 22:29

1 Answers1

2
  1. if the parent element is clicked,
    we check then if one of the buttons if clicked (so we can have the correct index always correct!

let rows = document.querySelectorAll(".row");

rows.forEach((el, index) => {
  // adding click event
  el.addEventListener("click", (e) => {
    let isBtnClicked = [...el.querySelectorAll("button")].some(
      (btn) => e.target == btn,
    );

    // if the button is clicked this means is true
    console.log(isBtnClicked, index, document.querySelectorAll(".row")[index]);
  });
});
/* delete this style, only debugging */

.row {
  border: 1px solid red;
  padding: 1rem;
}
<div class="container">
  <!-- 0 -->
  <div class="row">
    <button>Click</button>
  </div>
  <!-- 1 -->
  <div class="row">
    <button>Click</button>

    <!-- to test also with more buttons -->
    <button>Click</button>
    <button>Click</button>
  </div>
  <!-- 2 -->
  <div class="row">
    <button>Click</button>
  </div>
</div>

  1. if you want only the first button to be clicked, use this:

// only buttons that are inside .row class container

// if you use :first-child or :last-child inside the selector, 
// the if there is 2 buttons it will add the event only in one 
// and this means the index is always correct!!
let RowButtons = document.querySelectorAll(".row button:first-child");

// for loop
RowButtons.forEach((btn, index) => {

  // adding click event
  btn.addEventListener("click", () => {

    // getting the index of the button (technically is the same index of the .row)
    console.log(document.querySelectorAll(".row")[index]);
  });
});
/* delete this style, only debugging */

.row {
  border: 1px solid red;
  padding: 1rem;
}
<div class="container">
  <!-- 0 -->
  <div class="row">
    <button>Click</button>
  </div>
  <!-- 1 -->
  <div class="row">
    <button>Click</button>

    <!-- only first button will work using :first-child -->
    <button>this don't have event</button>
    <button>also this don't have event</button>
  </div>
  <!-- 2 -->
  <div class="row">
    <button>Click</button>
  </div>
</div>

  1. if you want only the first button, but with the first example logic

let rows = document.querySelectorAll(".row");

rows.forEach((el, index) => {
  // adding click event
  el.addEventListener("click", (e) => {
    // true means first button clicked, false not
    console.log(e.target == el.querySelector("button"))
  });
});
/* delete this style, only debugging */

.row {
  border: 1px solid red;
  padding: 1rem;
}
<div class="container">
  <!-- 0 -->
  <div class="row">
    <button>Click</button>
  </div>
  <!-- 1 -->
  <div class="row">
    <button>Click</button>

    <!-- only first button will work using :first-child -->
    <button>this don't have event</button>
    <button>also this don't have event</button>
  </div>
  <!-- 2 -->
  <div class="row">
    <button>Click</button>
  </div>
</div>
Laaouatni Anas
  • 4,199
  • 2
  • 7
  • 26
  • thanks for your affords but as i mentioned i cant use addEventListener because this divs ( class raw ) are created by loop after the page load that's why it cant read value of RowButtons because it is not present in the page at load time – gaurav joshi Aug 26 '22 at 10:16
  • @gauravjoshi check this: https://stackoverflow.com/a/70455549/17716837 I was having the same problem before, and this answer solves that. – Laaouatni Anas Aug 26 '22 at 11:43