简体   繁体   中英

How do I get the index of the element on a single click? (Pure JS)

I am trying to get the elements index on the first click. I am not sure what is going on with my eventListener but it only seems to work after i have clicked once on the element.

I tried changing the scope of the listener and debugging directly through "getListeners" of the element but to no avail.

I also tried to separate the listeners instead of nesting it but then it jsut doesn't work.

 const directory = document.querySelector('.directory') , card = document.getElementsByClassName('card') ; directory.addEventListener('click', () => { if (card) { for (let i = 0; i < card.length; i++) { card[i].addEventListener('click', () => { console.log(i); }); } } }) 
 .card { cursor: pointer; margin: 10px 0; text-align: center; } 
 <main class="directory"> <div class="card">0</div> <div class="card">1</div> <div class="card">2</div> </main> 

if the .card element is clicked then "i" should be printing to the console.

However, always the first click produces no console print.

Because you're adding events to the elements once the directory class is clicked, Instead you can add events directly on the elements

 const directory = document.querySelector('.directory'); const card = document.getElementsByClassName('card'); for (let i = 0; i < card.length; i++) { card[i].addEventListener('click', () => { console.log(i); }); } 
 .card { cursor: pointer; margin: 10px 0; text-align: center; } 
 <main class="directory"> <div class="card">0</div> <div class="card">1</div> <div class="card">2</div> </main> 

Because every time your directory is clicked, you're just adding new listeners - try clicking lots of buttons, you'll get lots of logs of the same number because all the listeners for the same event on the same element are all being fired. Add your listeners outside of the handler to prevent this from occurring:

 const directory = document.querySelector('.directory'); const card = document.getElementsByClassName('card'); for (let i = 0; i < card.length; i++) { card[i].addEventListener("click", () => { console.log(i); }); } 
 .card { cursor: pointer; margin: 10px 0; text-align: center; } 
 <main class="directory"> <div class="card">0</div> <div class="card">1</div> <div class="card">2</div> </main> 

Alternatively, use the principle in this answer to only add event listeners if they don't exist yet. This will avoid your event listeners being duplicated, but still will not fire the handler on the first click because the handler is being added on the click.

 const directory = document.querySelector('.directory'); const card = document.getElementsByClassName('card'); directory.addEventListener("click", () => { for (let i = 0; i < card.length; i++) { if (!card[i].onclick) card[i].onclick = () => console.log(i); } }); 
 .card { cursor: pointer; margin: 10px 0; text-align: center; } 
 <main class="directory"> <div class="card">0</div> <div class="card">1</div> <div class="card">2</div> </main> 

This a case of event delegation

 const directory = document.querySelector('.directory') directory.onclick = e => { if (e.target.className != 'card') return // ignore the other elements should be "clicked" ( like spaces ) console.clear() console.log( e.target.textContent ) } 
 .card { cursor: pointer; margin: 10px 0; text-align: center; border: 1px solid grey; } 
 <main class="directory"> <div class="card">0</div> <div class="card">1</div> <div class="card">2</div> </main> 

Have you tried writing it inside $(document).ready ?

$('document').ready(function(){
 /to-do
})

or you can use window.onload=functionToRun() without using jQuery

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM