I created a dropdown menu. But there I face a problem when I clicked outside keeping the dropdown menu open, the dropdown menu don't close. I try to add many javascript codes but in the end, I can't do it. Please someone please help me to fix this issue. I have given below my project code. I need this features outside click dropdown menu close only through this JS code.
function toggleDropDown(id) {
document.querySelectorAll('.dropdown-content').forEach(el => el.id === id ? el.classList.toggle('show') : el.classList.remove("show"));
}
body{
font-family: Arial, Helvetica, sans-serif;
}
.navbar {
overflow: hidden;
background-color: #333;
display:flex;
align-items:center;
justify-content: space-between;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown{
display:inline;
}
.dropdown .dropbtn {
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 260px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show{display:block;}
<div class="navbar">
<a href="#home">Home</a>
<a href="#news">News</a>
<div class="dropdown">
<button class="dropbtn" onclick="toggleDropDown('div1')">Dropdown1
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id=div1>
<p>Div1 dropdown</p>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="toggleDropDown('div2')">Dropdown2
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id=div2>
<p>Div2 dropdown</p>
</div>
</div>
</div>
One way to do this is to add an eventListener on the document. Then you check what has been clicked and if it involves your dropdown, do nothing, and if it doesn't involve your dropdown, then close the dropdowns.
This example uses closest() which will go up the parents of the clicked element to try and find one that has the class dropdown. If it finds one (not null), then we know we don't want to close the dropdown since the user is interacting with it. All other cases will close the dropdown.
document.addEventListener('click', (e) => {
// cases where we want to close the dropdown
if (e.target.closest(".dropdown") === null) {
document.querySelectorAll('.dropdown-content').forEach(el => el.classList.remove("show"));
}
});
function toggleDropDown(id) {
document.querySelectorAll('.dropdown-content').forEach(el => el.id === id ? el.classList.toggle('show') : el.classList.remove("show"));
}
body {
font-family: Arial, Helvetica, sans-serif;
}
.navbar {
overflow: hidden;
background-color: #333;
display: flex;
align-items: center;
justify-content: space-between;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
display: inline;
}
.dropdown .dropbtn {
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 260px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<div class="navbar">
<a href="#home">Home</a>
<a href="#news">News</a>
<div class="dropdown">
<button class="dropbtn" onclick="toggleDropDown('div1')">Dropdown1
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id="div1">
<p>Div1 dropdown</p>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="toggleDropDown('div2')">Dropdown2
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id="div2">
<p>Div2 dropdown</p>
</div>
</div>
</div>
</div>
Perhaps this solution, which is not the best and reliable, but works without JS, will be able to help you:
body {
font-family: Arial, Helvetica, sans-serif;
}
.navbar {
overflow: hidden;
background-color: #333;
display: flex;
align-items: center;
justify-content: space-between;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
display: inline;
}
.dropdown .dropbtn {
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 260px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
/*
added to CSS
*/
.dropbtn + .dropdown-content:hover, .dropbtn:focus + .dropdown-content {
display: block;
pointer-events: all !important;
}
<div class="navbar">
<a href="#home">Home</a>
<a href="#news">News</a>
<div class="dropdown">
<button class="dropbtn">Dropdown1
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<p>Div1 dropdown</p>
</div>
<div class="dropdown">
<button class="dropbtn">Dropdown2
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<p>Div2 dropdown</p>
</div>
</div>
</div>