[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");


Related Searches to javascript tutorial - How to detect a click outside an element ?