Почему два раза выполняется событие клика при закрытии меню?
делаю раскрывающуюся менюшку по клику, все работает, меню раскрывается, по нажатию вне области меню - закрывается, но есть проблема, что теперь по клику второй раз на кнопку, которая вызывает показ этой меню, она не закрывается. Как исправить то, что проходит два клика из-за цикла forEach?
// для поиска в header
const searchBg = document.querySelector('.search-bg'),
searchBtnAll = document.querySelectorAll('#searchBtn'),
headerSearch = document.querySelector('.header__search'),
headerSeacrhBtn = document.querySelectorAll('.search-bg__select-btn'),
dropDownMenuSearchContainer = document.querySelectorAll('.search-bg__select-container'),
searchInput = document.createElement('input'),
dropDownMenuSearch = document.createElement('div'),
searchInputPlaceholder = document.querySelectorAll('.search-bg__span');
// открытие поиска по кнопке
function searchFilter() {
openSearchBgBtn();
// открытие меню поиска
function openSearchBgBtn() {
searchBtnAll.forEach(btn => {
btn.addEventListener('click', (e) => {
if (!searchBg.classList.contains('active') && e.target !== btn) {
searchBg.classList.add('active');
searchBg.classList.remove('remove');
} else {
searchBg.classList.add('remove');
searchBg.classList.remove('active');
}
});
closeSearchFilter();
});
}
// закрытие меню при клике на свободную область
function closeSearchFilter() {
document.addEventListener('mousedown', (e) => {
if (!searchBg.contains(e.target)) {
searchBg.classList.add('remove');
searchBg.classList.remove('active');
}
console.log(e.target);
})
}
}
searchFilter();
.search-bg {
background: #FFFFFF;
-webkit-box-shadow: 0px 10px 10px rgba(0, 0, 0, 0.3);
box-shadow: 0px 10px 10px rgba(0, 0, 0, 0.3);
border-radius: 5px;
position: absolute;
top: 130px;
pointer-events: none;
padding: 25px 15px;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
z-index: 9999;
opacity: 0;
}
.search-bg.active {
top: 140px;
pointer-events: all;
opacity: 1;
}
.search-bg.remove {
top: 130px;
pointer-events: none;
opacity: 0;
}
.search-bg__select-container + .search-bg__select-container {
margin-top: 20px;
}
.search-bg__select-container {
width: 100%;
max-width: 230px;
position: relative;
}
.search-bg__select-container::after {
background: url(../img/icons/selectArrow.svg) 50% 50% no-repeat;
bottom: 0;
content: "";
height: auto;
opacity: 0.543;
position: absolute;
right: 8px;
top: 0;
-webkit-transition: -webkit-transform 0.1s ease-out;
transition: -webkit-transform 0.1s ease-out;
transition: transform 0.1s ease-out;
transition: transform 0.1s ease-out, -webkit-transform 0.1s ease-out;
width: 24px;
pointer-events: none;
}
.search-bg__select-btn {
width: 100%;
background: none;
text-align: left;
color: #000;
border: 1px solid #bcbcbc;
border-radius: 10px;
padding: 10px 30px 10px 10px;
position: relative;
}
.search-bg__select-btn::-webkit-input-placeholder {
color: #bcbcbc;
}
.search-bg__select-btn::-moz-placeholder {
color: #bcbcbc;
}
.search-bg__select-btn:-ms-input-placeholder {
color: #bcbcbc;
}
.search-bg__select-btn::-ms-input-placeholder {
color: #bcbcbc;
}
.search-bg__select-btn::placeholder {
color: #bcbcbc;
}
.search-bg__span {
color: #bcbcbc;
pointer-events: none;
}
.search-bg__select-dropdown {
position: absolute;
left: 0;
top: 60px;
}
.search-bg__select-dropdown.active {
opacity: 1;
top: 50px;
position: absolute;
left: 0;
top: 60px;
opacity: 0;
width: 100%;
border-radius: 10px;
overflow: hidden;
background-color: #fff;
-webkit-filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.25));
filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.25));
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
height: 150px;
z-index: 99999;
}
.search-bg__select-dropdown-list {
overflow-y: scroll;
height: 100%;
padding: 10px;
}
.search-bg__select-dropdown-item + .search-bg__select-dropdown-item {
margin-top: 20px;
}
.search-bg__select-dropdown-item {
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.search-bg__select-dropdown-item:hover {
color: #fd8223;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button class="" type="button" id="searchBtn">
<span class="">
Открыть меню
</span>
</button>
<!-- меню для поиска -->
<div class="search-bg">
<div class="search-bg__select-container">
<button class="search-bg__select-btn" type="button">
<span class="search-bg__span">
Категория
</span>
</button>
<!-- <div class="search-bg__select-dropdown">
<ul class="search-bg__select-dropdown-list">
<li class="search-bg__select-dropdown-item">Автотовары</li>
<li class="search-bg__select-dropdown-item">Бытовая техника</li>
<li class="search-bg__select-dropdown-item">Пример</li>
<li class="search-bg__select-dropdown-item">Автотовары</li>
<li class="search-bg__select-dropdown-item">Бытовая техника</li>
<li class="search-bg__select-dropdown-item">Пример</li>
</ul>
</div> -->
</div>
<div class="search-bg__select-container">
<button class="search-bg__select-btn" type="button">
<span class="search-bg__span">
Модель
</span>
</button>
<!-- <div class="search-bg__select-dropdown">
<ul class="search-bg__select-dropdown-list">
<li class="search-bg__select-dropdown-item">Автотовары</li>
<li class="search-bg__select-dropdown-item">Бытовая техника</li>
<li class="search-bg__select-dropdown-item">Пример</li>
<li class="search-bg__select-dropdown-item">Автотовары</li>
<li class="search-bg__select-dropdown-item">Бытовая техника</li>
<li class="search-bg__select-dropdown-item">Пример</li>
</ul>
</div> -->
</div>
</div>
</body>
</html>
Ответы (1 шт):
Автор решения: Laukhin Andrey
→ Ссылка
Событие mousedown у document всегда опережает click у кнопки. Поэтому меню успевает закрыться, затем снова открывается.
Чтобы всё заработало, нужно сделать две вещи:
- Заменить
mousedownнаclickдля document - Добавить
e.stopPropagation()в обработчик для кнопки, чтобы событие не дошло до document и не закрыло меню.