I have some HTML menus, which I show completely when a user clicks on the head of these menus. I would like to hide these elements when the user clicks outside the menus' area.
Is something like this possible with jQuery?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
Here is the vanilla JavaScript solution for future viewers.
Upon clicking any element within the document, if the clicked element's id is toggled, or the hidden element is not hidden and the hidden element does not contain the clicked element, toggle the element.
If you are going to have multiple toggles on the same page you can use something like this:
hidden
to the collapsible item.The event has a property called event.path of the element which is a "static ordered list of all its ancestors in tree order". To check if an event originated from a specific DOM element or one of its children, just check the path for that specific DOM element. It can also be used to check multiple elements by logically
OR
ing the element check in thesome
function.So for your case It should be
You can listen for a click event on
document
and then make sure#menucontainer
is not an ancestor or the target of the clicked element by using.closest()
.If it is not, then the clicked element is outside of the
#menucontainer
and you can safely hide it.Edit – 2017-06-23
You can also clean up after the event listener if you plan to dismiss the menu and want to stop listening for events. This function will clean up only the newly created listener, preserving any other click listeners on
document
. With ES2015 syntax:Edit – 2018-03-11
For those who don't want to use jQuery. Here's the above code in plain vanillaJS (ECMAScript6).
NOTE: This is based on Alex comment to just use
!element.contains(event.target)
instead of the jQuery part.But
element.closest()
is now also available in all major browsers (the W3C version differs a bit from the jQuery one). Polyfills can be found here: https://developer.mozilla.org/en-US/docs/Web/API/Element/closestI found this method in some jQuery calendar plugin.
Attach a click event to the document body which closes the window. Attach a separate click event to the container which stops propagation to the document body.
This should work: