简体   繁体   中英

How to get the child of a element with event.target

I'm trying to get the child elements of a div to toggle a class 'active'

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>

So i'm selecting all the divs with the data-dots attribute and then select the child of that div and add the class active. I tried with e.target.children but didnt work.

Thanks, I'm just trying to learn :)

In order to identify the first child, the easiest option is simply to use Element.querySelector() in place of 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');
}

The problem is, of course, that if no matching element is found by Element.querySelector() then it returns null ; which is where your script will raise an error. So, with that in mind, it makes sense to check that the element exists before you try to modify it:

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');
  }
}

It's also worth noting that EventTarget.addEventListener() passes the this element into the function, so rather than using:

e.target.querySelector(...)

it's entirely possible to simply write:

this.querySelector(...)

Unless, of course, handleClick() is rewritten as an Arrow function.

Demo:

 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> 

Or, if you wish to toggle the 'active' class you could, instead, use toggle() in place of 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> 

References:

e.target already is the clicked child of the element that you installed the listener on. You probably want to use e.currentTarget or this instead.
Then you can go using .getElementsByClassName() , .querySelector[All]() or .children from there.

You can also try this code.

 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')
        } 
     }
}

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