Find html element nearest to position (relative or absolute)

后端 未结 5 1806
隐瞒了意图╮
隐瞒了意图╮ 2020-12-10 01:52

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

相关标签:
5条回答
  • 2020-12-10 02:00

    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;
    };
    
    0 讨论(0)
  • 2020-12-10 02:01

    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.

    0 讨论(0)
  • 2020-12-10 02:05

    Or try the original jQuery function offsetparent(). From this page comes the next example:

    $( "li.item-a" ).offsetParent().css( "background-color", "red" );
    
    0 讨论(0)
  • 2020-12-10 02:08

    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:

    1. If the offset is inside one of the elements, it will be returned.
    2. I'm looping through four offsets, because this gives the best accuracy.

    Use it like this:

    $('div.myCollection').closestToOffset({left: 5, top: 5});
    
    0 讨论(0)
  • 2020-12-10 02:12

    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;
    }
    
    0 讨论(0)
提交回复
热议问题