[Solved-5 Solutions] How to detect a click outside an element ? - javascript tutorial
Problem:
We have some HTML menus, which would completely shows when a user clicks on the head of the menus. Otherwise We would like to hide these elements when the user clicks outside the menus area.
This possible with jQuery :
$("#menu_container").clickOutsideThisElement(function() {
// Hide the menu
});
Solution 1:
A click event is attached with the document body which closes the window. Another separate click event is attached with the window which stops propagation to the document body.
$(window).click(function() {
//Hide the menus if visible
});
$('#menu_container').click(function(event){
event.stopPropagation();
});
Solution 2:
Clicked event within the menu is not an the target of the clicked element by using .closest(). If the clicked element is outside of the menu and we can safely hide it.
$(document).click(function(event) {
if(!$(event.target).closest('#menu').length) {
if($('#menu').is(":visible")) {
$('#menu').hide();
}
}
});
- We can use event listener 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:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
if (!$(event.target).closest(selector).length) {
if ($(selector).is(':visible')) {
$(selector).hide()
removeClickListener()
}
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
- In JavaScript
function hideOnClickOutside(element) {
const outsideClickListener = event => {
if (!element.contains(event.target)) { // or use: event.target.closest(selector) === null
if (isVisible(element)) {
element.style.display = 'none'
removeClickListener()
}
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length
Solution 3:
Some jQuery calendar plugin contain a method to solve the problem:
function ClickOutsideCheck(event)
{
var eventl = event.target;
var popup = $('.popup:visible')[0];
if (popup==undefined)
return true;
while (true){
if (eventl == popup ) {
return true;
} else if (eventl == document) {
$(".popup").hide();
return false;
} else {
el = $(eventl).parent()[0];
}
}
};
$(document).bind('mousedown.popup', ClickOutsideCheck);
Solution 4:
A very simple solution to solve this:
$(document).mouseup(function (event)
{
var menu = $("OUR SELECTOR"); // Give we class or ID
if (!menu.is(event.target) && // If the target of the click is not the menu
menu.has(event.target).length === 0) // ... nor a descendant-child of the menu
{
menu.hide();
}
});
The above script will hide the div section of the menu if the div click event is triggered outside.
Solution 5:
The blur/focus event or any other tricky techniques are used instead of flow interruption and this simply match event flow:
$(document).on("click.menu-outside", function(event){
// Test if target and it's parent aren't menu
// That means the click event occur on document body
if(!$(event.target).parents().andSelf().is("#menu")){
// Click outisde the menu
// Hide the menus (but test if menus aren't already hidden)
}
});
To remove click outside event listener, simply:
$(document).off("click.menu-outside");