如何在html / javascript中隐藏下拉菜单

时间:2021-10-13 19:01:38

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?

我是Javascript的新手并尝试创建一个下拉菜单,当用户点击屏幕上的其他位置时,该菜单会隐藏。我的代码如下所示,为什么它不起作用?

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

2 个解决方案

#1


0  

event.target returns the element, if you want to retrieve the elements class name use .className , event.target.className

event.target返回元素,如果要检索元素类名,请使用.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'

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

建立在@ charlietfl的注释上的UPDATE添加此函数来检查祖先类并使用if(checkClass(event.tagent,'dropbtn')=== false)代替

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

更新:也许考虑使用模糊事件https://developer.mozilla.org/en-US/docs/Web/Events/blur

#2


0  

//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):

或者让我们走得更远(#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') );
}

#1


0  

event.target returns the element, if you want to retrieve the elements class name use .className , event.target.className

event.target返回元素,如果要检索元素类名,请使用.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'

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

建立在@ charlietfl的注释上的UPDATE添加此函数来检查祖先类并使用if(checkClass(event.tagent,'dropbtn')=== false)代替

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

更新:也许考虑使用模糊事件https://developer.mozilla.org/en-US/docs/Web/Events/blur

#2


0  

//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):

或者让我们走得更远(#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') );
}