I want to be able to close a popup menu when the user clicks outside. How can I accomplish this in pure JS?
Here is the code I'm currently working with:
function list(){
var r= document.getElementById('l2');
if (r.style.height==="0px"){
r.style.height="500px"
} else {
r.style.height="0px";}
}
#logo-menu img {
width: 4vw;
height: 2.79vw;
border-radius: 3px;
border: 0px solid rgba(0, 0, 0, 0.5);
transition: 0.3s;
z-index: 3;
margin: 0% 0% 0% 0%;
position: relative;
top: 0.0vw;
background: rgba(230, 230, 230, 1);
}
#logo-menu img:hover {
filter: invert(100%);
}
#logo-menu img:active {
filter: saturate(20);
transform: scale3d(1.01, 1.01, 1.01);
}
#l2 {
margin: -0.17% 0% 0% 0%;
}
#l2 ul {
width: 100%;
height: auto;
list-style-type: none;
padding: 0px 0px 4% 0px;
overflow: auto;
}
#l2 li a {
width: 20.7vw;
height: auto;
line-height: 1.2;
font-weight: bold;
font-size: 0.8vw;
word-break: break-word;
text-align: left;
color: black;
text-decoration: none;
background: rgba(255, 255, 255, 1);
display: block;
margin: 3.5% 0% -2% 1.5%;
padding: 1.5% 0% 2% 0%;
overflow: hidden;
border-radius: 5px;
float: left;
position: relative;
left: 4%;
}
#l2 p {
width: 100%;
height: auto;
position: relative;
left: 2%;
top: 0.5vw;
}
#l2 img {
width: 3.5vw;
height: 3.4vw;
float: left;
margin: 0.5% 0% 0% 1%;
border-radius: 5px;
background: rgba(255, 255, 255, 1);
}
#l2 li:hover>a {
background: rgba(0, 0, 0, 1);
color: white;
}
#l2 li a:hover img {
filter: invert(100%);
}
#l2 li:active>a {
background: rgba(20, 20, 20, 1);
color: white;
}
.dropdown-content {
background: rgba(235, 235, 235, 1);
overflow: auto;
width: 100%;
float: left;
height: 0px;
}
<div id="logo-menu"><img src=".png" onclick="list()" class="dropbtn" /></div>
<div id="l2" class="dropdown-content">
<ul>
<li>
<a href="list.html"><img src="pic1.png" />
<p>list item 1</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic2.png" />
<p>list item 2</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic3.png" />
<p>list item 3</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic4.png" />
<p>list item 3</p>
</a>
</li>
<li>
<a href="list.html"> <img src="pic5.png">
<p>list item 4</p>
</a>
</li>
<li>
<a href="list.html"> <img src="pic6 .png">
<p>list item 5</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic7 .png">
<p>list item 6</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic8 .png">
<p>list item 7</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic9 .png">
<p>list item 8</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic10 .png">
<p>list item 9</p>
</a>
</li>
</ul>
</div>
I want to be able to close a popup menu when the user clicks outside. How can I accomplish this in pure JS?
Here is the code I'm currently working with:
function list(){
var r= document.getElementById('l2');
if (r.style.height==="0px"){
r.style.height="500px"
} else {
r.style.height="0px";}
}
#logo-menu img {
width: 4vw;
height: 2.79vw;
border-radius: 3px;
border: 0px solid rgba(0, 0, 0, 0.5);
transition: 0.3s;
z-index: 3;
margin: 0% 0% 0% 0%;
position: relative;
top: 0.0vw;
background: rgba(230, 230, 230, 1);
}
#logo-menu img:hover {
filter: invert(100%);
}
#logo-menu img:active {
filter: saturate(20);
transform: scale3d(1.01, 1.01, 1.01);
}
#l2 {
margin: -0.17% 0% 0% 0%;
}
#l2 ul {
width: 100%;
height: auto;
list-style-type: none;
padding: 0px 0px 4% 0px;
overflow: auto;
}
#l2 li a {
width: 20.7vw;
height: auto;
line-height: 1.2;
font-weight: bold;
font-size: 0.8vw;
word-break: break-word;
text-align: left;
color: black;
text-decoration: none;
background: rgba(255, 255, 255, 1);
display: block;
margin: 3.5% 0% -2% 1.5%;
padding: 1.5% 0% 2% 0%;
overflow: hidden;
border-radius: 5px;
float: left;
position: relative;
left: 4%;
}
#l2 p {
width: 100%;
height: auto;
position: relative;
left: 2%;
top: 0.5vw;
}
#l2 img {
width: 3.5vw;
height: 3.4vw;
float: left;
margin: 0.5% 0% 0% 1%;
border-radius: 5px;
background: rgba(255, 255, 255, 1);
}
#l2 li:hover>a {
background: rgba(0, 0, 0, 1);
color: white;
}
#l2 li a:hover img {
filter: invert(100%);
}
#l2 li:active>a {
background: rgba(20, 20, 20, 1);
color: white;
}
.dropdown-content {
background: rgba(235, 235, 235, 1);
overflow: auto;
width: 100%;
float: left;
height: 0px;
}
<div id="logo-menu"><img src="https://png.icons8.com/metro/1600/star.png" onclick="list()" class="dropbtn" /></div>
<div id="l2" class="dropdown-content">
<ul>
<li>
<a href="list.html"><img src="pic1.png" />
<p>list item 1</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic2.png" />
<p>list item 2</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic3.png" />
<p>list item 3</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic4.png" />
<p>list item 3</p>
</a>
</li>
<li>
<a href="list.html"> <img src="pic5.png">
<p>list item 4</p>
</a>
</li>
<li>
<a href="list.html"> <img src="pic6 .png">
<p>list item 5</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic7 .png">
<p>list item 6</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic8 .png">
<p>list item 7</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic9 .png">
<p>list item 8</p>
</a>
</li>
<li>
<a href="list.html"><img src="pic10 .png">
<p>list item 9</p>
</a>
</li>
</ul>
</div>
Share
Improve this question
edited Mar 7, 2018 at 20:27
BonsaiOak
28.9k7 gold badges34 silver badges56 bronze badges
asked Mar 7, 2018 at 18:18
Jean-Pierre64Jean-Pierre64
1051 gold badge2 silver badges7 bronze badges
0
4 Answers
Reset to default 16You can try window.addEventListener. I've assumed outside of div means l2 & logo-menu div. Hopes below code helps you.
window.addEventListener('click', function(e){
if (!document.getElementById('l2').contains(e.target) && (!document.getElementById('logo-menu').contains(e.target))){
alert("Clicked outside l2 and logo-menu");
document.getElementById('l2').style.height="0px"; //the same code you've used to hide the menu
}
})
This worked for me
window.addEventListener('mouseup', function(e) {
var x = document.querySelector('#mylinks');
if (event.target != document.querySelector(".icon")) {
x.style.display = "none";
}
});
#mylinks
has the contents to be displayed on clicking .icon
I used style.display
to show or hide the contents.
You can achieve this functionality by attaching an event listener to the document object that listens for a click event. Then, within the event listener, you can check if the click target is inside the menu or not. If the click target is outside the menu, you can close the menu.
const menuButton = document.getElementById('menu-button');
const menu = document.getElementById('menu');
// show/hide the menu when the button is clicked
menuButton.addEventListener('click', () => {
menu.classList.toggle('hidden');
});
// hide the menu when a click event occurs outside the menu
document.addEventListener('click', (event) => {
if (!menu.contains(event.target) && !menuButton.contains(event.target)) {
menu.classList.add('hidden');
}
});
.hidden {
display: none;
}
#menu{
background: #f7f7f7;
}
<button id="menu-button">Menu</button>
<ul id="menu" class="hidden">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
You can use
document.getElementById(id).style.visibility = "hidden";
document.getElementById(id).style.visibility = "visible";
Inside of your function rather than setting px height.