Próbuję zdobyć elementy dziecka div, aby przełączyć klasę "aktywną"

JS

    const dots = document.querySelectorAll('[data-dots]');
    dots.forEach(dot => dot.addEventListener('click', handleClick));

    function handleClick(e) {
     e.target.getElementsByClassName('tb-drop').classList.toggle('active');
     console.log(e.target.getElementsByClassName('tb-drop'))
    }

HTML

       <div class="dots" data-dots>
         <i class="fas fa-ellipsis-v dots"></i>
         <div class="tb-drop">
            <i class="far fa-edit icon-grid"></i>
            <i class="fas fa-link icon-grid"></i>
         </div>
       </div>

Wybieram więc wszystkie divs z atrybutem kropek danych, a następnie wybierz dziecko tego div i dodać aktywną klasę. Próbowałem z e.target.children, ale nie działali.

Dzięki, próbuję się nauczyć :)

2
Jesus Sandrea 2 czerwiec 2018, 17:54

3 odpowiedzi

Najlepsza odpowiedź

Aby zidentyfikować pierwsze dziecko, najłatwiejsza opcja jest po prostu użycia Element.querySelector() zamiast Element.getElementsByClassName():

const dots = document.querySelectorAll('[data-dots]');
dots.forEach(dot => dot.addEventListener('click', handleClick));

function handleClick(e) {
  // Element.querySelector() returns the first - if any -
  // element matching the supplied CSS selector (element,
  // elements):
  e.target.querySelector('.tb-drop').classList.add('active');
}

Problem polega na tym, że jeśli nie znajduje się żaden pasujący element nie zostanie znaleziony przez Element.querySelector(), to zwraca null; Który jest tam, gdzie twój skrypt podniesie błąd. Mając to na uwadze, ma sens, aby sprawdzić, czy element istnieje, zanim spróbujesz go zmodyfikować:

const dots = document.querySelectorAll('[data-dots]');
dots.forEach(dot => dot.addEventListener('click', handleClick));

function handleClick(e) {
  let el = e.target.querySelector('.tb-drop');
  if (el) {
    el.classList.add('active');
  }
}

Warto również zauważyć, że EventTarget.addEventListener() przechodzi element this do funkcji, a nie przy użyciu:

e.target.querySelector(...)

Jest całkowicie możliwy do po prostu pisać:

this.querySelector(...)

Chyba że oczywiście handleClick() jest przepisany jako funkcja strzałki.

Próbny:

const dots = document.querySelectorAll('[data-dots]');
dots.forEach(dot => dot.addEventListener('click', handleClick));

function handleClick(e) {
  let el = e.target.querySelector('.tb-drop');
  if (el) {
    el.classList.add('active');
  }
}
div {
  display: block;
  border: 2px solid #000;
  padding: 0.5em;
}

i {
  display: inline-block;
  height: 1em;
}

::before {
  content: attr(class);
}

.active {
  color: limegreen;
}
<div class="dots" data-dots>
  <i class="fas fa-ellipsis-v dots"></i>
  <div class="tb-drop">
    <i class="far fa-edit icon-grid"></i>
    <i class="fas fa-link icon-grid"></i>
  </div>
</div>

Lub, jeśli chcesz przełączać "aktywną" klasę, możesz zamiast tego użyj toggle() zamiast tego add:

const dots = document.querySelectorAll('[data-dots]');
dots.forEach(dot => dot.addEventListener('click', handleClick));

function handleClick(e) {
  let el = e.target.querySelector('.tb-drop');
  if (el) {
    el.classList.toggle('active');
  }
}
div {
  display: block;
  border: 2px solid #000;
  padding: 0.5em;
}

i {
  display: inline-block;
  height: 1em;
}

::before {
  content: attr(class);
}

.active {
  color: limegreen;
}
<div class="dots" data-dots>
  <i class="fas fa-ellipsis-v dots"></i>
  <div class="tb-drop">
    <i class="far fa-edit icon-grid"></i>
    <i class="fas fa-link icon-grid"></i>
  </div>
</div>

Bibliografia:

8
David says reinstate Monica 2 czerwiec 2018, 15:16

e.target już jest kliknięte dziecko elementu, na którym instalujesz słuchacza. Zamiast tego prawdopodobnie chcesz użyć e.currentTarget lub this.
Następnie możesz iść za pomocą .getElementsByClassName(), .querySelector[All]() lub .children.

1
Bergi 2 czerwiec 2018, 15:14

Możesz także wypróbować ten kod.

 var dots = document.querySelectorAll('[data-dots]');
  for (var i = 0; i < dots.length; i++) {
      dots[i].addEventListener('click', function () {
          handleClick(this);
      }, false);
  }

function handleClick(object) {
     var container = object.getElementsByClassName('tb-drop')[0];
     if (container != undefined) {
        if (container.classList.contains('active')) {
            container.classList.remove('active')
        }else{
            container.classList.add('active')
        } 
     }
}
0
Vishal Maru 2 czerwiec 2018, 15:41