Skip to content

Instantly share code, notes, and snippets.

@badg0003
Last active June 21, 2024 16:43
Show Gist options
  • Save badg0003/18a974834cd9698f42ddbec923111bdb to your computer and use it in GitHub Desktop.
Save badg0003/18a974834cd9698f42ddbec923111bdb to your computer and use it in GitHub Desktop.
Detect outside click
/**
* Adds an event listener to detect clicks outside the specified element.
*
* @param {HTMLElement} element - The DOM element to detect outside clicks for.
* @param {Function} callback - The function to call when an outside click is detected.
* @param {HTMLElement} [toggleButton=null] - An optional toggle button element to ignore clicks on.
* @returns {Function} A function to remove the event listener.
*
* @example
* import onClickOutside from './onClickOutside';
*
* const element = document.querySelector('#my-element');
* const toggleButton = document.querySelector('button');
*
* // With toggle button
* const removeListenerWithToggle = onClickOutside(element, () => console.log('Hello with toggle button'), toggleButton);
*
* // Without toggle button
* const removeListenerWithoutToggle = onClickOutside(element, () => console.log('Hello without toggle button'));
*
* // To remove the event listener
* removeListenerWithToggle();
* removeListenerWithoutToggle();
*/
const onClickOutside = (element, callback, toggleButton = null) => {
if (!element || typeof callback !== 'function') {
console.error('Invalid arguments provided');
return;
}
const handler = e => {
const isClickInsideElement = element.contains(e.target);
const isClickOnToggleButton = toggleButton ? toggleButton.contains(e.target) : false;
if (!isClickInsideElement && !isClickOnToggleButton) {
callback();
}
};
document.addEventListener('click', handler);
return () => document.removeEventListener('click', handler); // Return a function to remove the event listener
};
export default onClickOutside;
@badg0003
Copy link
Author

Slightly revamped version of the original done by https://github.com/Chalarangelo/30-seconds-of-code/blob/master/content/snippets/js/s/listen-click-outside-event.md

I wanted to include the option of a toggle in case it is is not a child of the parent element that the event is tied to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment