Skip to content

Instantly share code, notes, and snippets.

@lyoshenka
Created May 24, 2015 15:13
Show Gist options
  • Save lyoshenka/403602aaeda2d6d87bf3 to your computer and use it in GitHub Desktop.
Save lyoshenka/403602aaeda2d6d87bf3 to your computer and use it in GitHub Desktop.
Detect a click outside of an element
/**
* Detects click outside element and calls callback()
*
* primaryElement - detect clicks outside this element. If element is removed from DOM, stop click detection.
* otherElements - optional array of elements that are also considered to be part of the primary elements (clicks in them are not external clicks)
* callback - function to call when an outclick is detected. Callback is passed the triggering Event.
*/
function onExternalClick(primaryElement, otherElements, callback) {
var uniqueCount = 0;
var ensureUniqueId = function(el) {
if (!$(el).attr('id')) {
$(el).attr('id', "unique-id-" + (++uniqueCount));
}
return el;
};
var externalClickCheck = function (event) {
var $target = $(event.target),
$primary = $(primaryElement),
elements = [],
clickInElements = false;
if (!callback && typeof(otherElements) === 'function') {
callback = otherElements;
otherElements = [];
}
if (!callback) { // wtf are we doing here?
return;
}
if (!$primary.closest(document.documentElement).length) { // if primary element is not in the DOM anymore, unbind this handler
$(document).off('mousedown', externalClickCheck); // each handler is assigned a unique id when it is bound, so only this instance of the handler will be unbound
return;
}
elements.push(ensureUniqueId($primary));
if (otherElements) {
otherElements.forEach(function(el) {
elements.push(ensureUniqueId($(el)));
});
}
for (var i = 0; i < elements.length; i++) {
if ($target.is(elements[i]) || $target.parents('#'+elements[i].attr('id')).length > 0) {
clickInElements = true;
break;
}
}
if (!clickInElements) {
callback(event);
}
};
$(document).on('mousedown', externalClickCheck);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment