JQuery kullanarak bir öğenin görünüme kaydırılmasını nasıl sağlayabilirim?


169

Kullanarak bir ızgara biçiminde görüntüleri ile bir HTML belgesi var <ul><li><img.... Tarayıcı penceresinde hem dikey hem de yatay kaydırma vardır.

Soru: Bir görüntüye tıkladığımda, <img>belgenin tamamını az önce tıkladığım görüntünün olduğu konuma kaydırmaya nasıl getirebilirim top:20px; left:20px?

Burada benzer gönderiler için bir göz attım ... JavaScript için oldukça yeni olmasına rağmen ve bunun kendim için nasıl yapıldığını anlamak istiyorum.


Yanıtlar:


192

Nasıl çalıştığını bilmek istediğiniz için, adım adım açıklayacağım.

İlk olarak bir işlevi resmin tıklama işleyicisi olarak bağlamak istersiniz:

$('#someImage').click(function () {
    // Code to do scrolling happens here
});

Bu, ile bir resme tıklama işleyicisini uygular id="someImage". Eğer bunu istiyorsanız tüm görüntüler, yerine '#someImage'ile 'img'.

Şimdi gerçek kaydırma kodu için:

  1. Görüntü ofsetlerini alın (belgeye göre):

    var offset = $(this).offset(); // Contains .top and .left
  2. 20 den çıkart topve left:

    offset.left -= 20;
    offset.top -= 20;
  3. Şimdi kaydırma üstü ve kaydırma-sol CSS özelliklerine animasyon <body>ve <html>:

    $('html, body').animate({
        scrollTop: offset.top,
        scrollLeft: offset.left
    });

3
Bu yalnızca basit düzenler için geçerlidir. .scrollIntoViewÖğeler birden fazla taşan kapta iç içe yerleştirildiğinde W3C yönteminin yaptığı tüm durumları işlemez .
natevw

2
Neden tekerleği yeniden icat etmeliyim? Element.scrollIntoView(): developer.mozilla.org/tr-TR/docs/Web/API/Element/scrollIntoView
Serge

@Serge, tüm tarayıcılarda uygulanmayan bir çalışma taslağı
John Smith

@JohnSmith dikkatle okudum bağlantı, "Tarayıcı Uyumluluğu" bölümünde okuyun, göreceksiniz hiçbir tarayıcı desteklemiyorscrollIntoView
Serge

@Serge Bunun için üzgünüm, fark etmedim, ayrıca scrollIntoViewOption (yeterince geniş desteklenmeyen) oldu. Sanırım yeterince iyi.
John Smith

377

scrollIntoViewTüm ana tarayıcılar tarafından desteklenen ve bir öğeyi görünüm penceresinin üst / soluyla (veya mümkün olduğunca yakın) hizalayacak bir DOM yöntemi vardır .

$("#myImage")[0].scrollIntoView();

Desteklenen tarayıcılarda seçenekler sunabilirsiniz:

$("#myImage")[0].scrollIntoView({
    behavior: "smooth", // or "auto" or "instant"
    block: "start" // or "end"
});

Alternatif olarak, tüm öğelerin benzersiz kimlikleri varsa, geri / ileri düğmesi desteği için nesnenin hashözelliğini değiştirebilirsiniz location:

$(document).delegate("img", function (e) {
    if (e.target.id)
        window.location.hash = e.target.id;
});

Bundan sonra scrollTop/ scrollLeftözelliklerini -20 ile ayarlayın :

document.body.scrollLeft -= 20;
document.body.scrollTop -= 20;

2
Teşekkür ederim! 5 diğer SO makalesi ve mükemmel çivilenmiş. Kullanım durumum, önyükleme iletişim kutusunda görünüme kaydırılması gereken bir kapsayıcıydı.
Stephen Patten

10
Not olarak: $("#myImage")[0].scrollIntoView(false);pencerenin altındaki öğeyi hizalar.
Philipp

1
Dikkat: "pürüzsüz" davranış yaygın olarak desteklenmez ve scrollIntoViewbir tür animasyon olmayan kullanıcılar için kafa karıştırıcı bir deneyim olabilir.
Cody Duval

1
@JohnHenckel: Bu yanlış, IE 5.5 bile scrollIntoViewboolean parametresiyle vardı . Daha sonra caniuse.com için bir çekme isteği göndereceğim.
Andy E

1
Not: Chrome'u kullanarak <td>öğeleri görünüme kaydıramadım, bunun yerine üst öğelerini ( <tr>) kaydırmak zorunda kaldım ve işe yaradı.
CrazyTim

13

Gördüğüm en basit çözüm

var offset = $("#target-element").offset();
$('html, body').animate({
    scrollTop: offset.top,
    scrollLeft: offset.left
}, 1000);

Eğitim Burada


Daha az basit hale getirme riski altında, yatay kaydırmayı da desteklemek için bunu düzenledim.
jpaugh

7

Öğeyi doğrudan görünüme kaydırmanın yöntemleri vardır, ancak bir öğeden göreceli bir noktaya kaydırmak istiyorsanız, bunu manuel olarak yapmanız gerekir:

Tıklama işleyicisinin içinde, öğenin belgeye göre konumunu alın, çıkarın 20ve kullanın window.scrollTo:

var pos = $(this).offset();
var top = pos.top - 20;
var left = pos.left - 20;
window.scrollTo((left < 0 ? 0 : left), (top < 0 ? 0 : top));

7

JQuery.scrollTo eklentisine bir göz atın . İşte bir demo .

Bu eklenti, yerel kaydırmanın ötesine geçen birçok seçeneğe sahiptir. size sunduklarının . Örneğin, kaydırmanın düzgün olmasını ayarlayabilir ve ardından kaydırma bittiğinde bir geri arama ayarlayabilirsiniz.

Ayrıca "scroll" ile etiketlenmiş tüm JQuery eklentilerine de göz atabilirsiniz .


Benim durumumda her tarayıcıda farklı ofsetler / pozisyonlar alıyordum ve bu eklenti benim için düzeltmeye yardımcı oldu! Teşekkürler!
LaurelB

4

İşte yerleşik tarayıcı işlevini güzel bir şekilde eşleştirmek için hızlı bir jQuery eklentisi:

$.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };

...

$('.my-elements').ensureVisible();

3

Deneme ve hata sonrası bu fonksiyon ile geldi, iframe ile de çalışır.

function bringElIntoView(el) {    
    var elOffset = el.offset();
    var $window = $(window);
    var windowScrollBottom = $window.scrollTop() + $window.height();
    var scrollToPos = -1;
    if (elOffset.top < $window.scrollTop()) // element is hidden in the top
        scrollToPos = elOffset.top;
    else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
        scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
    if (scrollToPos !== -1)
        $('html, body').animate({ scrollTop: scrollToPos });
}

2

Sadece bir ipucu. Yalnızca firefox'ta çalışır

Element.scrollIntoView ();


4
Bu, boole parametresine sahip olan veya hiç parametre olmayan tüm tarayıcılar için çalışır. Yalnızca daha gelişmiş nesne parametresi daha az desteklenir.
Risord

developer.mozilla.org/tr-TR/docs/Web/API/Element/scrollIntoView'a göre bunun için genel tarayıcı desteği eksikliği var
lfender6445

Artık sadece Opera Mini'yi yeterince destekliyor: caniuse.com/#search=scrollIntoView
John Magnolia

Bunun için bir dizi çok hafif poli dolgu var.
Martin James

1

Kullanıcı arayüzümde başparmak çubuğunda dikey bir başparmak listesi var Amaç, geçerli parmağınızı başparmak çubuğunun tam ortasına getirmekti. Onaylanan cevaptan başladım, ancak mevcut parmağı gerçekten ortalamak için birkaç ayar yapıldı. Umarım bu başka birine yardımcı olur.

biçimlendirme:

<ul id='thumbbar'>
    <li id='thumbbar-123'></li>
    <li id='thumbbar-124'></li>
    <li id='thumbbar-125'></li>
</ul>

jQuery:

// scroll the current thumb bar thumb into view
heightbar   = $('#thumbbar').height();
heightthumb = $('#thumbbar-' + pageid).height();
offsetbar   = $('#thumbbar').scrollTop();


$('#thumbbar').animate({
    scrollTop: offsetthumb.top - heightbar / 2 - offsetbar - 20
});

0

Aşağı veya yukarı kaydırmak için basit 2 adım.

Adım 1: Kaydırılabilir (konuşma) div'ın tam yüksekliğini elde edin.

Adım 2: Adım 1'de elde edilen değeri kullanarak kaydırılabilir (konuşma) div'e scrollTop uygulayın.

var fullHeight = $('#conversation')[0].scrollHeight;

$('#conversation').scrollTop(fullHeight);

Görüşme bölümündeki her ekleme için yukarıdaki adımlar uygulanmalıdır.


0

Her durumu ele alan bir çözüm bulmaya çalıştıktan sonra (kaydırmayı canlandırma seçenekleri, görünüme kaydırıldığında nesnenin etrafında dolgu, iframe gibi belirsiz durumlarda bile çalışır), sonunda buna kendi çözümümü yazdım. Diğer birçok çözüm başarısız olduğunda işe yaradığından, paylaşacağımı düşündüm:

function scrollIntoViewIfNeeded($target, options) {

    var options = options ? options : {},
    $win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
    $container = options.$container ? options.$container : $win,        
    padding = options.padding ? options.padding : 20,
    elemTop = $target.offset().top,
    elemHeight = $target.outerHeight(),
    containerTop = $container.scrollTop(),
    //Everything past this point is used only to get the container's visible height, which is needed to do this accurately
    containerHeight = $container.outerHeight(),
    winTop = $win.scrollTop(),
    winBot = winTop + $win.height(),
    containerVisibleTop = containerTop < winTop ? winTop : containerTop,
    containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
    containerVisibleHeight = containerVisibleBottom - containerVisibleTop;

    if (elemTop < containerTop) {
        //scroll up
        if (options.instant) {
            $container.scrollTop(elemTop - padding);
        } else {
            $container.animate({scrollTop: elemTop - padding}, options.animationOptions);
        }
    } else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
        //scroll down
        if (options.instant) {
            $container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
        } else {
            $container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
        }
    }
}

$target gerekiyorsa görünüme kaydırmak istediğiniz nesneyi içeren bir jQuery nesnesidir.

options (isteğe bağlı) bir nesneye iletilen aşağıdaki seçenekleri içerebilir:

options.$container- $ target içeren öğeyi işaret eden bir jQuery nesnesi (başka bir deyişle, dom'daki kaydırma çubuklarına sahip öğe). Varsayılan olarak $ target öğesini içeren ve bir iframe penceresi seçecek kadar akıllı penceredir. Mülk adına $ eklemeyi unutmayın.

options.padding- görünüme kaydırıldığında nesnenin üstüne veya altına eklemek için piksel cinsinden dolgu. Bu şekilde pencerenin kenarına doğru değil. Varsayılan değer 20'dir.

options.instant- true olarak ayarlanırsa, jQuery animate kullanılmaz ve kaydırma anında doğru konuma açılır. Varsayılanı false değerindedir.

options.animationOptions- jQuery animate işlevine iletmek istediğiniz tüm jQuery seçenekleri (bkz. http://api.jquery.com/animate/ ). Bununla, animasyonun süresini değiştirebilir veya kaydırma tamamlandığında bir geri arama işlevinin yürütülmesini sağlayabilirsiniz. Bu yalnızca options.instantfalse olarak ayarlandığında çalışır . Anında animasyona sahip olmanız ancak geri arama ile options.animationOptions.duration = 0kullanmanız gerekiyorsa, kullanmak yerine ayarlayın options.instant = true.

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.