Detecting Clicks Outside an Element

Detecting clicks outside an element is a common requirement in web development, particularly when working with dropdown menus, popovers, or other overlay elements. In this tutorial, we will explore how to achieve this using JavaScript and jQuery.

To detect clicks outside an element, we need to attach a click event listener to the document body and then check if the clicked element is within the bounds of our target element. If it’s not, we can perform the desired action, such as hiding the element.

Using jQuery

One way to achieve this using jQuery is by attaching a click event listener to the document body and then using the closest() method to check if the clicked element is within the bounds of our target element.

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

In this example, we’re checking if the clicked element is not within the #menucontainer element and if the #menucontainer element is visible. If both conditions are true, we hide the #menucontainer element.

Using Vanilla JavaScript

We can also achieve this using vanilla JavaScript without relying on jQuery.

function hideOnClickOutside(element) {
  const outsideClickListener = event => {
    if (!element.contains(event.target) && 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);

In this example, we’re using the contains() method to check if the clicked element is within the bounds of our target element. We’re also checking if the element is visible using the isVisible() function.

Handling Click-and-Drag Scenarios

In some cases, you may want to allow users to click-and-drag inside the element without closing it when they release the mouse outside the element. To handle this scenario, we can add additional logic to our event listeners.

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

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

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) { 
    element.style.display = 'none';
    removeClickListener();
    document.removeEventListener('mousedown', mouseDownListener); 
  }
}

In this example, we’re tracking the mouse down event and checking if the user has dragged the mouse outside the element. If they have, we don’t close the element.

Conclusion

Detecting clicks outside an element is a common requirement in web development. By using JavaScript and jQuery, we can achieve this functionality with ease. We’ve explored different approaches to handling this scenario, including using jQuery, vanilla JavaScript, and handling click-and-drag scenarios.

Leave a Reply

Your email address will not be published. Required fields are marked *