2010-02-25 182 views
21

给定绝对或相对位置(顶部&左侧)有什么办法可以获得最接近这些坐标的html元素吗?查找距离位置最近的html元素(相对或绝对)

或者,有没有什么方法可以制作一个选择器(或使用一些jQuery构造)来枚举元素,然后找到哪个接近所提供的坐标?假设这组元素很小且有限。

+0

我也作出你认为最接近的顶部/左边的“最接近”的假设?元素内的元素呢?如果它被包含,它是否与其父母“最接近”? – 2010-02-25 21:22:07

+0

这是一组预定义的元素,和一个平坦的列表,所以谢天谢地它不像其他一些情况那么复杂。最靠近的是顶部/左侧偏移量。 – psychotik 2010-02-25 21:32:07

回答

20

我已经建立了一个jQuery方法返回最接近元素来抵消,在集合中:

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; 
}; 

注:

  1. 如果偏移量是里面的的元素之一,它将被返回。
  2. 我通过四个偏移循环,因为这给出了最好的准确性。

使用方法如下:

$('div.myCollection').closestToOffset({left: 5, top: 5}); 
+0

我很好奇,如果你有很多元素(比如成千上万),那么性能会如何。 – pixelfreak 2011-07-28 01:43:32

+1

我正在使用这个功能,它运作良好,即使有很多元素。它应该是O(n)。无论如何,我不认为你可以减少总时间,所以试试看看它是否适合你。 – Sagi 2011-07-28 19:21:49

+0

如果div.myCollection包含嵌套元素,则可能需要继续查找,直到找到该点所在的最内层元素。 Document.elementFromPoint()也可能是一个很好的开始。 – 2015-07-01 12:50:42

1

我能想到的最好的方式是做一个搜索函数循环,循环遍历所有现有的元素并比较坐标,始终保留最近变量的副本。

多数民众赞成我可以想到这样做的方式,以及如果我受到你的限制,我会做什么。

+0

谢谢...这是我认为/知道的工作,但肯定会更喜欢另一种解决方案是可能的。 – psychotik 2010-02-25 21:19:32

+1

@psychotik:只要确保不要测量循环中元素的尺寸。每个度量都会触发浏览器重排。我认为只要“顶”和“左”是好的。 – 2010-02-25 21:38:58

1

通过所有元素循环是很容易的:

function getClosestElement(x, y) { 
    var elements, el, offset, dist, i, minDist, closestEl; 

    elements = $("body *"); 
    closestEl = elements.eq(i); 
    offset = closestEl.offset(); 
    offset.left += el.outerWidth()/2; // center of object 
    offset.top += el.outerHeight()/2; // middle of object 
    minDist = Math.sqrt((offset.left - x)*(offset.left - x) + (offset.top - y)*(offset.top - y)); 

    for (var i=0; i < elements.length; i++) { 
     el = elements.eq(i); 
     offset = el.offset(); 
     offset.left += el.outerWidth()/2; // center of object 
     offset.top += el.outerHeight()/2; // middle of object 
     dist = Math.sqrt((offset.left - x)*(offset.left - x) + (offset.top - y)*(offset.top - y)); 
     if (dist < minDist) { 
      minDist = dist; 
      closestEl = el; 
     } 
    } 

    return closestEl; 
+1

为什么这个臭虫缠身的答案已被允许在这里坐了五年,随时准备惹恼下一个吸盘来,我不知道。 – HeyHeyJC 2015-04-16 13:59:35

-1

或者试试原来的jQuery函数offsetparent()。从这个页面来的下一个例子:

$("li.item-a").offsetParent().css("background-color", "red"); 
+0

最接近位置,而不是DOM – koMah 2017-05-19 21:11:40

相关问题