2010-02-25 88 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

相關問題