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.