-1

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.

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40

4 Answers4

2

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>
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • 1
    You also might want to drop the `if (card)`, it's always a truthy (even if empty) collection object – Bergi Jul 21 '19 at 13:54
  • @Code Maniac It still doesnt work in my project. I ran it in codepen and also deleted my other listener but something else might be the problem. Would you mind looking at the repo? github.com/ZealousSloth/Techdegree-Project-8 line 84 - 90 app.js thanks! – Zealous Sloth Jul 21 '19 at 16:47
  • @ZealousSloth what error you're getting ? is there any error on console ? – Code Maniac Jul 21 '19 at 17:16
  • I dont get any error, but i solved the problem by just indexing each element upon creation and then getting the 'data-set' once clicked by placing the listener outside as suggested. Sorry for my late response! Thank you so much for your help! – Zealous Sloth Jul 24 '19 at 12:20
0

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>
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
0

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>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

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

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

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

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
fachrilinggo
  • 243
  • 1
  • 2
  • 7