Taşan bir Div içindeki bir öğeye nasıl geçebilirim?


159

Bir div içinde sadece bir seferde 5 gösterebilen 20 liste öğem var. 10 numaralı öğeye ve sonra 20 numaralı öğeye kaydırmanın iyi bir yolu nedir? Tüm eşyaların yüksekliğini biliyorum.

scrollToEklenti yapar, ama onun kaynağı gerçekten içine almadan anlamak süper kolay değildir. Bu eklentiyi kullanmak istemiyorum.

Diyelim ki 2 elemanları alır bir işlevi var diyelim $parentDiv, $innerListItemne $innerListItem.offset().topde $innerListItem.positon().topbana $ parentDiv için doğru scrollTop verir.


Güncellemeniz nedeniyle cevabım kaldırıldı. Ama güven bana, daha önce aynı tutum vardı, pozisyon ve kenar boşlukları, vb ile çok sayıda tarayıcı tuhaflıkları var ... eklenti çok daha basit bir yol ve daha az zaman alıcı ve GZip sadece 3k önce .
Nick Craver

1
Yine de scrollTo eklentisini kullanın. Zor değil. $("#container").scrollTo(target, duration, options). Hedef sadece bir #anchor. Bitti.
Ryan McGeary

bir eklenti olmadan bunu yapmak için orada bilgi olmalı gibi görünüyor. yarın kaynak okumaya başlayacak
mkoryak

5
@mkoryak - Bilgi orada, ama tarayıcı tuhaflıkları için hesap yaptığınızda, temelde .scrollTo eklentisi ile sonuçlanır , o zaman neden tekerleği her zaman yeniden icat?
Nick Craver

1
IMHO, muhtemelen .scrollTo dışında ne gerek tam alt kümesi ile bitireceğiz bugün . .ScrollTo IE9, FF4 ve Chrome 6 için güncellendi süre Fakat birkaç ay sonra, sen baştan başlamak zorunda kalacak ... 3k Bunu önlemek için çok düşük bir fiyat gibi görünüyor.
Wim

Yanıtlar:


236

$innerListItem.position().topAslında görecelidir .scrollTop()ilk konumlandırılmış atasının. Dolayısıyla, doğru $parentDiv.scrollTop()değeri hesaplamanın yolu $parentDiv, konumlandırıldığından emin olarak başlamaktır . Zaten açık bir ifadesi yoksa positionkullanın position: relative. Elemanların $innerListItemve tüm atalarının $parentDivaçık bir konuma sahip olmaları gerekmiyor. Şimdi ile şuraya gidebilirsiniz $innerListItem:

// Scroll to the top
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top);

// Scroll to the center
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top
    - $parentDiv.height()/2 + $innerListItem.height()/2);

152

Bu benim eklentim (öğeyi listenin en üstüne yerleştirecek. Özellikle için overflow-y : auto. İle çalışmayabilir overflow-x!):

NOT : elemsayfanın kaydırılacağı bir öğenin HTML seçicisidir. : Gibi jQuery tarafından desteklenen herhangi bir şey #myid, div.myclass, $(jquery object), [dom nesne], vs.

jQuery.fn.scrollTo = function(elem, speed) { 
    $(this).animate({
        scrollTop:  $(this).scrollTop() - $(this).offset().top + $(elem).offset().top 
    }, speed == undefined ? 1000 : speed); 
    return this; 
};

Animasyona ihtiyacınız yoksa, şunu kullanın:

jQuery.fn.scrollTo = function(elem) { 
    $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top); 
    return this; 
};

Nasıl kullanılır:

$("#overflow_div").scrollTo("#innerItem");
$("#overflow_div").scrollTo("#innerItem", 2000); //custom animation speed 

Not: #innerItemiçeride herhangi bir yerde olabilir #overflow_div. Gerçekten doğrudan bir çocuk olmak zorunda değil.

Firefox (23) ve Chrome (28) 'de test edilmiştir.

Tüm sayfayı kaydırmak istiyorsanız, bu soruyu kontrol edin .


nedir elem?? hiç açıklamıyorsun.
vsync

Eğer fn.scroll içinde $ değiştirmek yerine jQuery için takas daha iyi kilometre / çatışma olmayan olsun
Barry Carlyon

Bu büyük kusur, kapsamı $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem, $(this)).offset().top);
içermiyor

1
Sayfa ile öğe arasında üst kenar boşluğu bırakmak istiyorsanız (bazı durumlarda daha iyi görünebilir), örneğin, 10px gibi çıkarma yapın $(this).scrollTop() - $(this).offset().top + $(elem).offset().top - 10.
lepe

Firefox ve Chrome (veya diğer tarayıcılar) arasında konum farklarınız varsa, html kodunuzu kontrol edin ( bu hata raporuna bakın )
lepe

34

Glenn Moss'un cevabını, taşma divının sayfanın üstünde olmayabilir.

parentDiv.scrollTop(parentDiv.scrollTop() + (innerListItem.position().top - parentDiv.position().top) - (parentDiv.height()/2) + (innerListItem.height()/2)  )

Ben duyarlı bir şablon ile bir google haritalar uygulamasında kullanıyordum. 800 pikselden büyük çözünürlükte liste haritanın sol tarafındaydı. <800 çözünürlüğünde liste haritanın altındaydı.


6

Yukarıdaki cevaplar, taşma elemanının içinde görünse bile, iç elemanı taşma elemanının üstüne yerleştirecektir. Öğe görünmüyorsa kaydırma konumunu değiştirmeyecek şekilde değiştirdim.

jQuery.fn.scrollTo = function(elem, speed) {
    var $this = jQuery(this);
    var $this_top = $this.offset().top;
    var $this_bottom = $this_top + $this.height();
    var $elem = jQuery(elem);
    var $elem_top = $elem.offset().top;
    var $elem_bottom = $elem_top + $elem.height();

    if ($elem_top > $this_top && $elem_bottom < $this_bottom) {
        // in view so don't do anything
        return;
    }
    var new_scroll_top;
    if ($elem_top < $this_top) {
        new_scroll_top = {scrollTop: $this.scrollTop() - $this_top + $elem_top};
    } else {
        new_scroll_top = {scrollTop: $elem_bottom - $this_bottom + $this.scrollTop()};
    }
    $this.animate(new_scroll_top, speed === undefined ? 100 : speed);
    return this;
};

Bu bana yardımcı oldu !! Bkz. Stackoverflow.com/questions/48283932/…
gen b.

1

Hayatımı kolaylaştırmak için şu 2 işlevi yazıyorum:

function scrollToTop(elem, parent, speed) {
    var scrollOffset = parent.scrollTop() + elem.offset().top;
    parent.animate({scrollTop:scrollOffset}, speed);
    // parent.scrollTop(scrollOffset, speed);
}

function scrollToCenter(elem, parent, speed) {
    var elOffset = elem.offset().top;
    var elHeight = elem.height();
    var parentViewTop = parent.offset().top;
    var parentHeight = parent.innerHeight();
    var offset;

    if (elHeight >= parentHeight) {
        offset = elOffset;
    } else {
        margin = (parentHeight - elHeight)/2;
        offset = elOffset - margin;
    }

    var scrollOffset = parent.scrollTop() + offset - parentViewTop;

    parent.animate({scrollTop:scrollOffset}, speed);
    // parent.scrollTop(scrollOffset, speed);
}

Ve onları kullanın:

scrollToTop($innerListItem, $parentDiv, 200);
// or
scrollToCenter($innerListItem, $parentDiv, 200);

elem.offset().topekranın üstünden hesaplıyor. Ben üst öğeden hesaplamak istiyorum. Bunu nasıl yaparım ?
Santosh

0

Onunla çok uzun bir süre oynadıktan sonra, ben bu kadar geldim:

    jQuery.fn.scrollTo = function (elem) {
        var b = $(elem);
        this.scrollTop(b.position().top + b.height() - this.height());
    };

ve buna böyle diyorum

$("#basketListGridHolder").scrollTo('tr[data-uid="' + basketID + '"]');
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.