Belgeye göre öğenin konumunu bulma


113

Belge / gövde / tarayıcı penceresine göre bir öğe konumunu belirlemenin en kolay yolu nedir?

Şu anda kullanıyorum .offsetLeft/offsetTop , ancak bu yöntem size yalnızca ana öğeye göre konum verir, bu nedenle konumu gövde / tarayıcı penceresi / belge konumuna göre görmek için body öğesinin kaç ebeveyni belirlemeniz gerekir.

Bu yöntem aynı zamanda zahmetlidir.

Yanıtlar:


59

DOM'un en offsetParentüst düzeyine kadar ilerleyebilirsiniz.

function getOffsetLeft( elem )
{
    var offsetLeft = 0;
    do {
      if ( !isNaN( elem.offsetLeft ) )
      {
          offsetLeft += elem.offsetLeft;
      }
    } while( elem = elem.offsetParent );
    return offsetLeft;
}

28
Herhangi bir ebeveynin (özellikle html öğesi !!!) kenar boşlukları, dolguları veya kenarlıkları olduğunda hayır yoktur.
Flaş Thunder

kenar boşluğuyla ilgili olarak ... kutu boyutlandırmasını border-

Öncelikle, kutu boyutuna göre sınır ve marjı dikkate alıp almayacağınıza karar vermelisiniz. İkinci olarak, daraltılmış marj dikkate alınmalıdır. Ve son olarak, gelecekte bu cevabı daha da kötüleştirecek daha karmaşık bir durum olacak.
xianshenglu

6
Bu neden kabul edilen cevap? Bu modası geçmiş ve kötü performans gösteriyor. Kendinize bir iyilik yapın ve diğer yanıtlarda önerildiği gibi getBoundingClientRect () kullanın.
Fabian von Ellerts

177

Sen alabilirsiniz üst ve sol böyle DOM katetmeden:

function getCoords(elem) { // crossbrowser version
    var box = elem.getBoundingClientRect();

    var body = document.body;
    var docEl = document.documentElement;

    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;

    var clientTop = docEl.clientTop || body.clientTop || 0;
    var clientLeft = docEl.clientLeft || body.clientLeft || 0;

    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;

    return { top: Math.round(top), left: Math.round(left) };
}

6
Bu cevap, ebeveynlerin ofsetlerini hesaba katmaz. Sadece görüntü alanına göre
Nickey

3
@Nickey bu doğru değil — görüntü alanı konumu ve kaydırma ofset kontrolleri, tüm belgeye göre koordinatları verir.
natchiketa

1
Mobil cihazlarda hatalı olabilir stackoverflow.com/a/32623832/962634 Araştırma gerekiyor
basil

1
Neden clientTop / clientLeft'i çıkarıyorsunuz?
Teemoh

1
@Teemoh clientTop / clientLeft öğedeki sınır değerlerine karşılık gelir <html>.
Raphael Rafatpanah

98

element.getBoundingClientRect()Görüntü alanına göre öğe konumunu almak için kullanabilirsiniz .

Ardından document.documentElement.scrollTop, görüntü alanı ofsetini hesaplamak için kullanın .

İkisinin toplamı, belgeye göre öğe konumunu verecektir:

element.getBoundingClientRect().top + document.documentElement.scrollTop

10
Görüntü alanına göre, belgeye göre aynı değildir. Sayfa biraz aşağı kaydırılırsa, görüntü alanına göre üst kısım, belgeye göre üstten daha küçük bir sayı olacaktır.
MrVimes

14
görüntü alanına göre başlar ve belgeye göre almak için scrollY ekler.
Joaquin Cuenca Abela

2
document.documentElement.scrollTopSafari'de çalışmıyor, window.scrollYbunun yerine kullanın
Fabian von Ellerts

7

Kullanmayı öneririm

element.getBoundingClientRect()

offsetLeft , offsetTop ve offsetParent aracılığıyla manuel ofset hesaplaması yerine burada önerildiği gibi . burada önerildiği gibi Bazı durumlarda * manuel geçiş geçersiz sonuçlar verir. Bu Plunker'a bakın: http://plnkr.co/pC8Kgj

* Öğe, statik (= varsayılan) konumlandırmalı kaydırılabilir bir üst öğenin içinde olduğunda.


Kaydırma hesaplamasının ayrıca scrollLeft ve scrollTop'u da buna dahil ederek çalışmasını sağlayabilirsiniz.
Ben J

Ama CSS3 dönüşümlerini buldum offsetLeftve offsetTophesaba katmadım, ki getBoundingClientRect()bu. Bu, sonuçların geçersiz olabileceği bir durumdur. İhtiyacınız varsa, kullanarak bir elemanın ebeveyn (gibi offsetLeft) göreli ofsetini alabilirsiniz (element.getBoundingClientRect().left - parent.getBoundingClientRect().left).
Ben J

def daha yükseğe çıkmalı; bu değerler çok daha kullanışlıdır ve hepsi bir arada!
mix3d

7

document-offset( 3. taraf komut dosyası ) ilginç ve buradaki diğer yanıtlardan gelen yaklaşımlardan yararlanıyor gibi görünüyor.

Misal:

var offset = require('document-offset')
var target = document.getElementById('target')
console.log(offset(target))
// => {top: 69, left: 108} 

5

OffsetTop / offsetLeft'i düşüren uç durumlarla uğraşırken aşağıdaki yöntemi en güvenilir buldum.

function getPosition(element) {
    var clientRect = element.getBoundingClientRect();
    return {left: clientRect.left + document.body.scrollLeft,
            top: clientRect.top + document.body.scrollTop};
}

4

Belgeye göre bir elemanın çeşitli konumlarının x ve y koordinatlarını almak isteyenler için.

const getCoords = (element, position) => {
  const { top, left, width, height } = element.getBoundingClientRect();
  let point;
  switch (position) {
    case "top left":
      point = {
        x: left + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "center left":
      point = {
        x: left + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "bottom left":
      point = {
        x: left + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
  }
  return point;
};

kullanım

  • getCoords(document.querySelector('selector'), 'center')

  • getCoords(document.querySelector('selector'), 'bottom right')

  • getCoords(document.querySelector('selector'), 'top center')


2

JQuery kullanmaktan çekinmiyorsanız, offset()işlevi kullanabilirsiniz . Bu işlev hakkında daha fazla bilgi edinmek istiyorsanız belgelere bakın .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.