Skip to content

Instantly share code, notes, and snippets.

@egfx
Last active August 29, 2015 14:16
Show Gist options
  • Save egfx/ec496cafe61db369bde9 to your computer and use it in GitHub Desktop.
Save egfx/ec496cafe61db369bde9 to your computer and use it in GitHub Desktop.
Find the physically closest DOM element
(function($){
$.fn.physicallyClosest = function() {
var $this = this,
selector = "body *",
options;
if(typeof arguments[0] === "string") {
selector = arguments[0];
}
else if(typeof arguments[0] === "object") {
options = arguments[0];
}
if(typeof arguments[1] === "object") {
options = arguments[1];
}
var settings = {
'excludeChildren': false,
'excludeDescendants': false,
'reverse': false
};
if(options) {
$.extend(settings, options);
}
var selectedY = this.offset().top + (this.height() / 2),
selectedX = this.offset().left + (this.width() / 2),
closestFound;
$(selector).each(function() {
if(settings.excludeChildren) {
if($(this).parent().get(0) == $this.get(0)) {
return 1;
}
}
if(settings.excludeDescendants) {
var isDescendant = false;
$(this).parents().each(function() {
if($(this).get(0) == $this.get(0)) {
isDescendant = true;
return false; //Break
}
});
if(isDescendant) {
return 1; //Continue
}
}
var currentY = $(this).offset().top + ($(this).height() / 2),
currentX = $(this).offset().left + ($(this).width() / 2),
yDiff = currentY - selectedY,
xDiff = currentX - selectedX,
c = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
if(closestFound) {
if(!settings.reverse && c != 0 && c < closestFound.distance) {
closestFound = { element: this, distance: c };
}
else if(settings.reverse && c != 0 && c > closestFound.distance) {
closestFound = { element: this, distance: c };
}
}
else {
closestFound = { element: this, distance: c };
}
});
return $(closestFound.element);
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment