Reputation: 3375
I'm trying to hide the dropdown menu
when is clicked outside, but no success so far.
I've read about 10 or more threads here and tried different solutions.
This is the dropdown menu
that I have
<div class="dropdown">
<button onclick="myFunction()">Per Page</button>
<div id="openmenu" class="dropdown-content">
<a href="">15</a>
<a href="">20</a>
</div>
</div>
And the showing part
function myFunction() {
document.getElementById("openmenu").classList.toggle("show");
}
I've tried this so far
Try 1:
function boxCloser(e){
if(e.target.id != 'openmenu'){
document.body.removeEventListener('click', boxCloser, false);
$('.dropdown-content').hide();
}
}
Try 2:
$(document).on("click touchend", function(){
$(".dropdown-content").removeClass("open");
});
Try 3:
$('body').not(".dropdown").off('click').on('click',function(){$(".dropdown").removeClass("show")});
and try 4
function hideDiv(){
document.getElementsByClassName('dropdown')[0].classList.remove('hidden');
}
document.addEventListener("click", hideDiv, false);
None of them close the menu when I click outside the dropdown
part.
Upvotes: 0
Views: 4056
Reputation: 3185
$(document).on("click", function(event){
var $trigger = $(".dropdown");
if($trigger !== event.target && !$trigger.has(event.target).length){
$(".dropdown-content").slideUp("fast");
}
});
try this
Upvotes: 0
Reputation: 3183
Looks like you're puzzled with class names of your elements.
In different attempts you provided you use either openmenu
ID, or dropdown-content
class, or dropdown
class for selecting the element, as well as different methods for hiding and showing the dropdown (show
, hidden
, open
classes, etc.)
To fully answer your question one would need to see the corresponding CSS code: what styles do you use for showing and hiding dropdown? Also, how do you bind that boxCloser()
function to some user event?
Anyway, assuming that you're able to open the dropdown, and the problem is only when closing it, try the following.
Update HTML of the button: remove onclick
attribute and add a class name to it
<button class="dropdown-button">Per Page</button>
function onClick(event) {
// if clicked on .dropdown-button, find .dropdown-content near it and toggle it
if (event.target.classList.contains("dropdown-button")) {
var content = event.target.parentElement.getElementsByClassName("dropdown-content")[0];
if (content)
content.classList.toggle("show");
} else if (!event.target.matches(".dropdown *")) {
// if clicked outside of dropdown, hide all dropdowns
var allDropdowns = document.getElementsByClassName("dropdown-content");
for (var i = 0; i < allDropdowns.length; i++)
allDropdowns[i].classList.remove("show");
}
}
document.addEventListener("click", onClick);
I don't know what your CSS is, so make sure you do not refer to #openmenu
element by ID and use class name instead:
.dropdown-content {
display: none;
}
.dropdown-content.show {
display: block;
}
This should also work for multiple dropdowns and without jQuery.
If you want to use jQuery, the script can be simplified:
function onClick(event) {
if ($(event.target).is(".dropdown-button"))
$(event.target).parent().find(".dropdown-content").toggleClass("show");
else if ($(event.target).closest(".dropdown").length === 0)
$(".dropdown-content").removeClass("show");
}
$(document).click(onClick);
Note that this code prevents dropdowns from hiding when you click inside of open dropdowns. It also allows multiple dropdowns to be opened simultaneously. You can modify the code to achieve the other behavior in these aspects, but it's outside of the scope of this question.
Upvotes: 0
Reputation: 1105
I'm assuming you have jQuery included as some of the question examples use it. The 'isMenuOpen' variable would have to be set to true when opening the menu. Though it is not strictly necessary and you can omit it.
working example: https://jsfiddle.net/3ut2yqj1/
<button id="open_menu"> open menu </button>
<div id="menu" style="border: 1px solid black; width:100px; height:100px; display:none"> </div>
var isMenuOpen= false;
$("#open_menu").on('click',function()
{
isMenuOpen = true;
$("#menu").show();
});
$(document).on('click', function (e) {
if (($(e.target).closest('#menu').length == 0) && ($(e.target).closest('#open_menu').length == 0)) {
if (isMenuOpen == true) {
isMenuOpen = false;
$("#menu").hide();
}
}
});
Upvotes: 1
Reputation: 53198
Since you seem to have jQuery as an option, the following code is more suited as it will support multiple dropdowns (it isn't dependent upon the ID of the elements involved).
You need to stop the event propagating up the DOM when you click on the button, and then assign a click
handler to document
. This is achieved by returning false
from the click handler on the button.
Please see the working demo below:
$(document).on("click touchend", function(e){
$(".dropdown-content").removeClass("show");
});
$('.dropdown-content').prev('button').on('click', function(e) {
$(this).siblings('.dropdown-content').toggleClass('show');
return false;
});
.dropdown-content {
display: none;
}
.dropdown-content.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown">
<button>Per Page</button>
<div id="openmenu" class="dropdown-content">
<a href="">15</a>
<a href="">20</a>
</div>
</div>
Upvotes: 1