How to detect click outside element?
P粉113938880
P粉113938880 2023-08-23 13:37:35
0
2
478
<p>I have some HTML menus that I fully display when the user clicks on the header of these menus. I want to hide these elements when the user clicks outside the menu area. </p> <p>Is this possible using jQuery? </p> <pre class="brush:php;toolbar:false;">$("#menuscontainer").clickOutsideThisElement(function() { // Hide the menus });</pre> <p><br /></p>
P粉113938880
P粉113938880

reply all(2)
P粉212114661

You can listen to the click event on document and then make sure that the #menucontainer is not an ancestor or target of the clicked element by using .closest().

If not, the clicked element is outside the #menucontainer and you can safely hide it.

$(document).click(function(event) { 
  var $target = $(event.target);
  if(!$target.closest('#menucontainer').length && 
  $('#menucontainer').is(":visible")) {
    $('#menucontainer').hide();
  }        
});

Edited – June 23, 2017

You can also clean up after the event listener if you plan to close the menu and want to stop listening to events. This function will only clean up newly created listeners, leaving any other click listeners on document. Use ES2015 syntax:

export function hideOnClickOutside(selector) {
  const outsideClickListener = (event) => {
    const $target = $(event.target);
    if (!$target.closest(selector).length && $(selector).is(':visible')) {
        $(selector).hide();
        removeClickListener();
    }
  }

  const removeClickListener = () => {
    document.removeEventListener('click', outsideClickListener);
  }

  document.addEventListener('click', outsideClickListener);
}

Edited – November 3, 2018

For those who don't want to use jQuery. This is the plain vanillaJS (ECMAScript6) code above.

function hideOnClickOutside(element) {
    const outsideClickListener = event => {
        if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null
          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 ); // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js 

Notice: This is based on Alex's comment, just use !element.contains(event.target) instead of the jQuery part.

But element.closest() also now works in all major browsers (the W3C version is slightly different from the jQuery version). Polyfill can be found here: Element.closest()

Edit – 2020-05-21

If you want the user to be able to click and drag inside an element and then release the mouse outside the element without closing the element:

...
      let lastMouseDownX = 0;
      let lastMouseDownY = 0;
      let lastMouseDownWasOutside = false;

      const mouseDownListener = (event: MouseEvent) => {
        lastMouseDownX = event.offsetX;
        lastMouseDownY = event.offsetY;
        lastMouseDownWasOutside = !$(event.target).closest(element).length;
      }
      document.addEventListener('mousedown', mouseDownListener);

In outsideClickListener:

const outsideClickListener = event => {
        const deltaX = event.offsetX - lastMouseDownX;
        const deltaY = event.offsetY - lastMouseDownY;
        const distSq = (deltaX * deltaX) + (deltaY * deltaY);
        const isDrag = distSq > 3;
        const isDragException = isDrag && !lastMouseDownWasOutside;

        if (!element.contains(event.target) && isVisible(element) && !isDragException) { // or use: event.target.closest(selector) === null
          element.style.display = 'none';
          removeClickListener();
          document.removeEventListener('mousedown', mouseDownListener); // Or add this line to removeClickListener()
        }
    }
P粉333186285

Attach a click event to the document body of the closed window. Attach a separate click event to the container to stop propagation to the document body.

$(window).click(function() {
  //Hide the menus if visible
});

$('#menucontainer').click(function(event){
  event.stopPropagation();
});
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template