Given absolute or relative position (top & left) is there any way to get the nearest html element to these co-ordinates?
Or alternately, is there any way to craf
Fixed the bugs to the previous answer (also cleaned up to ES6):
const getClosestElement = (x, y) => {
const elements = $('body *');
let closestEl = elements.eq(0); //initialize to first element
let offset = closestEl.offset();
offset.left += closestEl.outerWidth() / 2; // center of object
offset.top += closestEl.outerHeight() / 2; // middle of object
let minDist = Math.sqrt((offset.left - x) * (offset.left - x) + (offset.top - y) * (offset.top - y));
elements.each((i) => {
const el = elements.eq(i);
offset = el.offset();
offset.left += el.outerWidth() / 2; // center of object
offset.top += el.outerHeight() / 2; // middle of object
const dist = Math.sqrt((offset.left - x) * (offset.left - x) + (offset.top - y) * (offset.top - y));
if (dist < minDist) {
minDist = dist;
closestEl = el;
}
});
return closestEl;
};
The best way I can think of to do this would be to have a search function loop that loops through all your existing elements and compares the co-ordinates, keeping a copy of the nearest variable all the time.
Thats the way I can think of doing this, and what I would do if I was under your constraints.
Or try the original jQuery function offsetparent(). From this page comes the next example:
$( "li.item-a" ).offsetParent().css( "background-color", "red" );
I've built a jQuery method that returns closest element to offset, within the collection:
jQuery.fn.closestToOffset = function(offset) {
var el = null,
elOffset,
x = offset.left,
y = offset.top,
distance,
dx,
dy,
minDistance;
this.each(function() {
var $t = $(this);
elOffset = $t.offset();
right = elOffset.left + $t.width();
bottom = elOffset.top + $t.height();
if (
x >= elOffset.left &&
x <= right &&
y >= elOffset.top &&
y <= bottom
) {
el = $t;
return false;
}
var offsets = [
[elOffset.left, elOffset.top],
[right, elOffset.top],
[elOffset.left, bottom],
[right, bottom],
];
for (var off in offsets) {
dx = offsets[off][0] - x;
dy = offsets[off][1] - y;
distance = Math.sqrt(dx * dx + dy * dy);
if (minDistance === undefined || distance < minDistance) {
minDistance = distance;
el = $t;
}
}
});
return el;
};
Notes:
Use it like this:
$('div.myCollection').closestToOffset({left: 5, top: 5});
I used @Felix answer and applied it to vanilla Js for my requirements, I know it's an old question but if anyone needs it
function getClosestChoice(x, y, elements) {
let closestEl,
minDist,
offset;
elements.forEach((el) => {
offset = { left: el.offsetLeft, top: el.offsetTop };
offset.left += el.offsetWidth / 2;
offset.top += el.offsetHeight / 2;
const dist = Math.sqrt(
(offset.left - x) * (offset.left - x) + (offset.top - y) * (offset.top - y)
);
if (!minDist || dist < minDist) {
minDist = dist;
closestEl = el;
}
});
return closestEl;
}