I am new to Javascript and trying to create a dropdown menu that hides when a user clicks on another spot on the screen. My code is shown below, why doesn't it work?
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
event.target
returns the element, if you want to retrieve the elements class name use .className
, event.target.className
https://developer.mozilla.org/en-US/docs/Web/API/Event/target
replace !event.target.matches('.dropbtn')
with event.target.className!= 'dropbtn'
UPDATE building on @charlietfl's comment add this function to check for ancestor class and use if(checkClass (event.tagent, 'dropbtn') === false)
instead
function checkClass (el, cls) {
if(el.classList.contains(cls)) return true;
return typeof el.parentElement !== null ? checkClass (el.parentElement, cls) : false;
}
UPDATE: maybe look into using the blur event https://developer.mozilla.org/en-US/docs/Web/Events/blur
//first a mod of WalksAway's `checkClass()`
function checkClass(el, cls) {
return !!el && (el.classList.contains(cls) || checkClass(el.parentElement, cls));
}
//or with a loop:
function checkClass(el, cls) {
while(el){
if(el.classList.contains(cls)) return true;
el = el.parentElement;
}
return false;
}
and a modification of your code:
//a handy little utility-function:
function $$(selector, context){
if(!context || !context.querySelectorAll) context = document;
return Array.from( context.querySelectorAll( selector ) );
}
window.onclick = function(event) {
if(!checkClass(event.target, '.dropbtn')){
$$('.dropdown-content.show').forEach(function(el){
el.classList.remove('show');
});
}
}
or let's go even a bit further (#ES6, #FP):
//more utils:
var traverseUp = el => {
for(var result = []; el; el = el.parentElement) result.push( el );
return result;
}
var hasClass = cls => el => el.classList.contains(cls);
var addClass = cls => el => el.classList.add(cls);
var removeClass = cls => el => el.classList.remove(cls);
window.onclick = function(event) {
if( !traverseUp(event.target).some( hasClass('.dropbtn') ) )
$$('.dropdown-content.show').forEach( removeClass('show') );
}
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.