-1

I want to get the index value of the div which has been clicked. I have 6 divs. When I click on them using e.target from the whole document, I want to get the index position of the clicked one from the 6 divs

 const myall = Array.from(document.querySelectorAll('.same'));
 const thum_container = Array.from(document.querySelectorAll('.item-thumb'));

document.addEventListener('click', (e) => {
        if(e.target.classList.contains('item-thumb')){
            
            
            alert('lets see ' + thum_container.indexOf(e.target));     
         }
     }); 
<div id="modal-product-thumb-item" style="border-radius: 12px; height: 100%; border: 1px solid #e8e8e1;  overflow: hidden; background: #f1f1f1;">
                                                                    <a  class="item-thumb">
                                                                        <h2>
                                                                        one
                                                                        </h2>
                                                                    </a>
                                                                </div>
                                                                
<div  style="border-radius: 12px; height: 100%; border: 1px solid #e8e8e1;  overflow: hidden; background: #f1f1f1;">
                                                                    <a  class="item-thumb">
                                                                        <h2>
                                                                        two
                                                                        </h2>
                                                                    </a>
                                                                </div>
                                                                
<div  style="border-radius: 12px; height: 100%; border: 1px solid #e8e8e1;  overflow: hidden; background: #f1f1f1;">
                                                                    <a  class="item-thumb">
                                                                        <h2>
                                                                        three
                                                                        </h2>
                                                                    </a>
                                                                </div>   
                                                                
                                                                <div  style="border-radius: 12px; height: 100%; border: 1px solid #e8e8e1;  overflow: hidden; background: #f1f1f1;">
                                                                    <a  class="item-thumb">
                                                                        <h2>
                                                                        foure
                                                                        </h2>
                                                                    </a>
                                                                </div> 
                                                                
                                                                <div  style="border-radius: 12px; height: 100%; border: 1px solid #e8e8e1;  overflow: hidden; background: #f1f1f1;">
                                                                    <a  class="item-thumb">
                                                                        <h2>
                                                                        five
                                                                        </h2>
                                                                    </a>
                                                                </div> 
                                                                
                                                                <div  style="border-radius: 12px; height: 100%; border: 1px solid #e8e8e1;  overflow: hidden; background: #f1f1f1;">
                                                                    <a  class="item-thumb">
                                                                        <h2>
                                                                        six
                                                                        </h2>
                                                                    </a>
                                                                </div> 

I want to get the index value of the div which has been clicked. I have 6 divs, when I click on them using e.target from the whole document, I want to get the index position of the clicked one from the 6 divs

const myall = document.querySelectorAll('.container');

document.addEventListener('click', (e) => {
        if(e.target.classList.contains('same')){
             myall.forEach((eachitem, eachindex) => {
                eachitem.addEventListener('click', () => {
                    alert('lets see ' + eachindex);
                });
            });  
         }
     });
<div class="container">
<div class="same">1</div>
<div class="same">2</div>
<div class="same">3</div>
<div class="same">4</div>
<div class="same">5</div>
<div class="same">6</div>
</div>
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Leith
  • 135
  • 10
  • 1
    I think you could apply https://stackoverflow.com/questions/378365/finding-dom-node-index to get the index of the element. I don't think there's a native call for getting the index so it needs one of those helpers to figure it out through traversal. – Juho Vepsäläinen Apr 12 '22 at 15:47
  • `e.target.textContent` will return the numbers if that's what you ment – Yosi Leibman Apr 12 '22 at 15:47
  • Does this answer your question? [Get child node index](https://stackoverflow.com/questions/5913927/get-child-node-index) – Sᴀᴍ Onᴇᴌᴀ Apr 12 '22 at 17:29

2 Answers2

2

Just get an Array of the desired div elements and then use indexOf to find the index of the clicked element.

const myall = Array.from(document.querySelectorAll('.container .same'));

document.addEventListener('click', (e) => {
   if(e.target.classList.contains('same')){
      console.log(myall.indexOf(e.target));  
    }
});
<div class="container">
  <div class="same">1</div>
  <div class="same">2</div>
  <div class="same">3</div>
  <div class="same">4</div>
  <div class="same">5</div>
  <div class="same">6</div>
</div>

Here is the same solution using the code from your Fiddle with additional elements so you can see that it works regardless of the number of elements:

document.addEventListener('click', (e) => {
  if(e.target.classList.contains('item-thumb')){
  
    // Get an array of just the elements in this container
    const items = Array.from(e.target.closest("div.modal-product-thumb-item").querySelectorAll(".item-thumb"));
    alert('lets see ' + items.indexOf(e.target));
  }
});
div.modal-product-thumb-item {
  border-radius: 12px; 
  border: 1px solid #e8e8e1;  
  overflow: hidden; 
  background: #f1f1f1;
  margin-bottom:3px;
}
<div class="modal-product-thumb-item">
  <h2 class="item-thumb">Item</h2>
</div>
<div class="modal-product-thumb-item">
  <h2 class="item-thumb">Item</h2>
  <h2 class="item-thumb">Item</h2>
</div>
<div class="modal-product-thumb-item">
  <h2 class="item-thumb">Item</h2>
  <h2 class="item-thumb">Item</h2>
  <h2 class="item-thumb">Item</h2>
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • its working in this example, but in my another case, I have `e.target.closest('#quick-shop-desktop .item-thumb')){ const myall = document.querySelectorAll('.item-thumb');` when I click on the element, it is giving the value -1 every time – Leith Apr 12 '22 at 16:03
  • 2
    Can you post that code as a [mcve]? – ggorlen Apr 12 '22 at 16:06
  • @Leith We'd need to see that code. And, your approach isn't what I show in my answer. – Scott Marcus Apr 12 '22 at 16:09
  • @ScottMarcus https://jsfiddle.net/jyedo9ng/1/, should I update the post with the original? – Leith Apr 12 '22 at 16:20
  • @ScottMarcus, I want to get the index of the clicked item thumb, I also updated the code above – Leith Apr 12 '22 at 16:27
  • 1
    @Leith Your problem in the Fiddle is that you are including a `.` in your `classList.contains()` code. `contains` assumes you are working with a class, so no `.` is used. – Scott Marcus Apr 12 '22 at 16:30
  • 1
    @Leith Also, you shouldn't be using `a` elements if you aren't navigating anywhere. The classes should be placed on the `h2` elements. [See this forked Fiddle which works](https://jsfiddle.net/dvm40baj/4/). – Scott Marcus Apr 12 '22 at 16:32
  • @ScottMarcus, I updated it, still not solved? – Leith Apr 12 '22 at 16:32
  • @ScottMarcus, thank you so much for helping, but why its not working on a? I want to use it on a because as it seems, if there is a container and have more than two elements inside it, would I do on both the elements? – Leith Apr 12 '22 at 16:35
  • @Leith Because `a` elements that don't have `href` attributes are not clickable and therefore the `click` event won't bubble to it. `` elements should only be used for navigation. Any other use for them will cause problems for those who use assistive technologies, like screen readers. – Scott Marcus Apr 12 '22 at 16:36
  • @ScottMarcus its not working on div also instead of `a` – Leith Apr 12 '22 at 16:39
  • @ScottMarcus, I know its not need, but maybe I want to add it on a container which has three elements inside it. Evey time I can't do it on each item – Leith Apr 12 '22 at 16:44
  • @ScottMarcus, but its not working on a `div` container also – Leith Apr 12 '22 at 16:46
  • @Leith I've updated my answer to show your Fiddle scenario and with different amounts of `h2` elements in various containers. No additional `div` or `a` elements are needed and it doesn't matter how many `h2` elements you have in each container. – Scott Marcus Apr 12 '22 at 16:55
  • @ScottMarcus, I am really sorry, but I still not get the problem, `` I want it on the seconddiv – Leith Apr 12 '22 at 17:10
  • @Leith To be clear, the element that the event is being handled at is `document`. There, the actual element that triggered the event is referenced by `e.target`. Since the user will see and click on the `h2`, that is `e.target`, not the wrapper `div` element(s)`. – Scott Marcus Apr 12 '22 at 17:20
  • @ScottMarcus, https://jsfiddle.net/gufzq3b1/1/, in this, I am not getting back the array when clicking on the images – Leith Apr 13 '22 at 03:54
  • 1
    @Leith That is a different issue than what your question here is asking about. I have shown and explained how to solve the question you posted with simple code. Please consider marking this as the answer and then post a new question about your array. – Scott Marcus Apr 13 '22 at 13:12
0

The easiest way to do this is to target all elements first. Loop through them and add a listener.

const myall = document.querySelectorAll('.container .same');

myall.forEach((element, index) => {
    element.addEventListener('click', (e) => {
        console.log('div text',e.target.textContent);
        console.log('index of the div', index);
    });
});  
tiborK
  • 385
  • 1
  • 6
  • That certainly isn't the "easiest" way. Mostly because it doesn't do what the OP is asking. She wants the index of the element within the group, not the contents of the element. And, there's no need for each element to have its own event handler. See my answer. – Scott Marcus Apr 12 '22 at 15:59
  • same, I do the same ealier, but what is happening is, on the first click, nothing happens, but on secnd click there is 1 console log of the index, and on second click there are 2 consolelog of the index, and the number keeps increasing as there are click? – Leith Apr 12 '22 at 16:08
  • @ggorlen Adding a loop and setting up individual event handlers is resource intensive and complicates the code unnecessarily. Event delegation is the way to go for a problem like this and as you can see from my answer, it's far simpler with less processing and memory implications. – Scott Marcus Apr 12 '22 at 16:11
  • @ScottMarcus Event delegation gives better performance, yes, but that doesn't mean other answers need to be downvoted – tiborK Apr 12 '22 at 16:18
  • 1
    @tiborK I down voted because this answer is unnecessarily involved and less performant. It's not a good solution to the problem and one that would certainly come under scrutiny in a code review. Those kinds of answers certainly do warrant a down vote. – Scott Marcus Apr 12 '22 at 16:22
  • @ggorlen `indexOf` searches through the Array, not the DOM. Array searching is optimized and exceptionally fast. You seem to want to dispute very simple and well established concepts here. Yes, this code "works". Working code is not always good code. – Scott Marcus Apr 12 '22 at 16:35