Bir öğenin tarayıcı görünümüne göre en üst konumuna nasıl getirilir?


173

Bir öğenin, tarayıcının görünüm penceresine (tüm sayfanın değil, sayfanın görüntülendiği görünüm) göre konumunu almak istiyorum. Bu JavaScript ile nasıl yapılabilir?

Çok teşekkürler


2
Bu sorunun gerçekten güzel bir çözümü olan stackoverflow.com/questions/211703/… 'a benzediğini düşünüyorum .
Jakob Runge

1
@ JakobRunge, 2013'te "güzel" miydi?
Iulian Onofrei

1
Bir çözümü kabul etmeyi düşünün.
Iulian Onofrei

Yanıtlar:


306

Mevcut cevaplar artık güncel değil. Yerel getBoundingClientRect()yöntem uzun süredir var ve sorunun tam olarak ne istediğini yapıyor. Ayrıca tüm tarayıcılarda desteklenir (IE 5 dahil, öyle görünüyor!)

Gönderen MDN sayfa :

Döndürülen değer, kenarlık kutusunu tanımlayan salt okunur sol, üst, sağ ve alt özellikleri piksel olarak, sol üst görünümün sol üst köşesine göre piksel olarak içeren bir TextRectangle nesnesidir .

Şöyle kullanırsınız:

var viewportOffset = el.getBoundingClientRect();
// these are relative to the viewport, i.e. the window
var top = viewportOffset.top;
var left = viewportOffset.left;

3
Tarayıcı yakınlaştırma (Android Chrome) kullanıldığında bu doğru çalışmayabilir. @Rism'in çözümü ( aşağıya bakınız ) bu durumda çalışır
Dmitry

4
Çoğu durumda iyi, ancak öğenin gömülü iframe içinde olmadığını varsayar, değil mi? Soru, tarayıcının penceresine göre sormaktır. El.getBoundingClientRect (), tarayıcı penceresine değil, iframe penceresine göre döner.
cakidnyc

6
Soru, tarayıcının penceresine göre sormaktır.
Dmitry Dvornikov

2
@Denilson getBoundingClientRect().topbenim IE11 değil 0 döndürür. Herhangi bir çözüm var mı.
Arif

@Arif: Üzgünüm, ancak sorununuzu yeniden oluşturamıyorum. Bunu IE11'de test ettim ve hala sonuçlar aldım: codepen.io/denilsonsa/pen/ypqyXj
Denilson Sá Maia

57

Benim durumumda, kaydırma konusunda güvende olmak için, window.scroll öğesini denkleme ekledim:

var element = document.getElementById('myElement');
var topPos = element.getBoundingClientRect().top + window.scrollY;
var leftPos = element.getBoundingClientRect().left + window.scrollX;

Bu, kaydırılmış olsa bile, öğenin belge üzerindeki gerçek göreli konumunu almamı sağlar.


2
Kaydırma konumunu çıkarmak yerine eklemeniz gerekmiyor mu?
Iulian Onofrei

Cevabı iptal ettim ama yine de, @lulian Onofrei haklı. Lütfen düzenleyin.
pmrotule

@Fabio getBoundingClientRect().topbenim IE11 değil 0 döndürür. Size herhangi bir çözüm var.
Arif

1
@Arif window.scrollY || window.pageYOffsetdesteği artırabilir
Fabian von Ellerts

@FabianvonEllerts :)
Arif

15

Düzenle: Sayfa kaydırmayı hesaba katan bir kod ekleyin.

function findPos(id) {
    var node = document.getElementById(id);     
    var curtop = 0;
    var curtopscroll = 0;
    if (node.offsetParent) {
        do {
            curtop += node.offsetTop;
            curtopscroll += node.offsetParent ? node.offsetParent.scrollTop : 0;
        } while (node = node.offsetParent);

        alert(curtop - curtopscroll);
    }
}

İd argümanı, ofsetini istediğiniz öğenin kimliğidir. Quirksmode yayınından uyarlandı .


1
Cevabınız için teşekkürler, ancak sorumu yanlış anladığınızı düşünüyorum, sayfaya göre bir öğenin üst kısmının nasıl alınacağını biliyorum, yapmaya çalıştığım şey 'görünüm penceresine' (yani tarayıcı penceresi) göre konum elde etmektir , belge değil)
Waleed Eissa

Üzgünüm, 'bakış açısı' kullanımınız beni attı. Yani, tarayıcı kromunu, yani yer işaretleri araç çubuğunu, konum çubuğunu vb.
Derek Swingley

Hayır, sadece sayfayı gördüğünüz pencere. Sayfa kaydırılırsa, bu belgenin üst kısmından farklı olacaktır, aksi takdirde aynıdır.
Waleed Eissa

Ah tamam, anlıyorum. Bunu nasıl yapacağımdan emin değilim ... bir şey bulursam cevabımı düzenler.
Derek Swingley

Yukarıdaki kodu biraz daha çirkin yaptım ama işe yarıyor ... use offsetParent.scrollTop
Derek Swingley

11
var element =  document.querySelector('selector');
var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

Görünüşe göre bu belgenin üst kısmından hesaplanıyor gibi görünüyor
Scott Leonard

5

Deneyebilirsin:

node.offsetTop - window.scrollY

Opera'da tanımlanan viewport meta etiketi ile çalışır.


8
Ben anlamak belgelerine doğru, offsetTopen yakın konumlandırılmış elemana görecelidir. Hangi, sayfa yapısına bağlı olarak, kök öğe olabilir veya olmayabilir.
Denilson Sá Maia

5

jQuery bunu oldukça zarif bir şekilde uygular. JQuery'nin kaynağına bakarsanız, bunun offsettemel olarak nasıl uygulandığını göreceksiniz:

var rect = elem.getBoundingClientRect();
var win = elem.ownerDocument.defaultView;

return {
    top: rect.top + win.pageYOffset,
    left: rect.left + win.pageXOffset
};

2

Bu sayfadaki işlev , tarayıcı görünüm bağlantı noktasına göre geçirilen bir öğenin üst, sol, yükseklik ve genişlik koordinatlarına sahip bir dikdörtgen döndürür.

    localToGlobal: function( _el ) {
       var target = _el,
       target_width = target.offsetWidth,
       target_height = target.offsetHeight,
       target_left = target.offsetLeft,
       target_top = target.offsetTop,
       gleft = 0,
       gtop = 0,
       rect = {};

       var moonwalk = function( _parent ) {
        if (!!_parent) {
            gleft += _parent.offsetLeft;
            gtop += _parent.offsetTop;
            moonwalk( _parent.offsetParent );
        } else {
            return rect = {
            top: target.offsetTop + gtop,
            left: target.offsetLeft + gleft,
            bottom: (target.offsetTop + gtop) + target_height,
            right: (target.offsetLeft + gleft) + target_width
            };
        }
    };
        moonwalk( target.offsetParent );
        return rect;
}

2
function inViewport(element) {
    let bounds = element.getBoundingClientRect();
    let viewWidth = document.documentElement.clientWidth;
    let viewHeight = document.documentElement.clientHeight;

    if (bounds['left'] < 0) return false;
    if (bounds['top'] < 0) return false;
    if (bounds['right'] > viewWidth) return false;
    if (bounds['bottom'] > viewHeight) return false;

    return true;
}

kaynak


1

Tüm cevaplar için teşekkürler. Prototip'in zaten bunu yapan bir işlevi var gibi görünüyor (page () işlevi). Fonksiyonun kaynak kodunu görüntüleyerek, önce sayfaya göre eleman ofset pozisyonunu hesapladığını (yani belgenin üstü), sonra scrollTop'u bundan çıkardığını gördüm. Daha fazla ayrıntı için prototipin kaynak koduna bakın.


İyi karar. Büyük olasılıkla tarayıcılarda aynı sonucu vermeleri daha olası olduğundan büyük kütüphanelerden biriyle gitmek en iyisidir. Merak ediyorsanız, cevabımı kontrol edin. Kod orada yapacak ama nasıl tarayıcılar arasında tutacağım hakkında hiçbir fikrim yok.
Derek Swingley

1

btn1Web sayfasında kimliğine sahip bir öğe ve ayrıca jQuery dahil olduğunu varsayalım. Bu, Chrome, FireFox, IE> = 9 ve Edge'in tüm modern tarayıcılarında çalıştı. jQuery yalnızca belgeye göre konumu belirlemek için kullanılır.

var screenRelativeTop =  $("#btn1").offset().top - (window.scrollY || 
                                            window.pageYOffset || document.body.scrollTop);

var screenRelativeLeft =  $("#btn1").offset().left - (window.scrollX ||
                                           window.pageXOffset || document.body.scrollLeft);

1
jQuery JavaScript'tir. "% 100 vanilya / saf JS değil"
hungerstar

Evet, demek istediğim buydu.
Sunil

1

Bazen getBoundingClientRect()nesnenin özellik değeri IE için 0 değerini gösterir. Bu durumda display = 'block'eleman için ayar yapmanız gerekir . Ofset almak için tüm tarayıcı için aşağıdaki kodu kullanabilirsiniz.

JQuery işlevselliğini genişletme:

(function($) {
    jQuery.fn.weOffset = function () {
        var de = document.documentElement;
        $(this).css("display", "block");
        var box = $(this).get(0).getBoundingClientRect();
        var top = box.top + window.pageYOffset - de.clientTop;
        var left = box.left + window.pageXOffset - de.clientLeft;
        return { top: top, left: left };
    };
}(jQuery));

Kullanım:

var elementOffset = $("#" + elementId).weOffset();
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.