Vraag Hoe scrol ik naar een element in een overvolle Div?


Ik heb 20 lijstitems in een div die slechts 5 tegelijk kunnen weergeven. Wat is een goede manier om naar item # 10 te scrollen en vervolgens item # 20? Ik weet de hoogte van alle items.

De scrollTo plugin doet dit, maar de bron is niet super eenvoudig te begrijpen zonder er echt in te raken. Ik wil deze plug-in niet gebruiken.

Laten we zeggen dat ik een functie heb die twee elementen nodig heeft $parentDiv, $innerListItem, geen van beide $innerListItem.offset().top noch $innerListItem.positon().top geeft me de juiste scrollTop voor $ parentDiv.


132
2018-02-27 02:28


oorsprong


antwoorden:


De $innerListItem.position().top is eigenlijk relatief ten opzichte van de .scrollTop() van zijn eerste gepositioneerde voorouder. Dus de manier om het juiste te berekenen $parentDiv.scrollTop() waarde is om te beginnen door ervoor te zorgen dat $parentDiv is gepositioneerd. Als het nog niet expliciet is position, gebruik position: relative. De elementen $innerListItem en al zijn voorouders tot $parentDiv hoeft geen expliciete positie te hebben. Nu kunt u naar de bladeren $innerListItem met:

// 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);

203
2018-03-10 23:06



Dit is mijn eigen plugin (zal het element bovenaan de lijst plaatsen. Speciaal voor overflow-y : auto. Mag niet werken met overflow-x!):

NOTITIE: elem is de HTML-selector van een element waarnaar naar de pagina wordt gescrolld. Alles wat door jQuery wordt ondersteund, zoals: #myid, div.myclass, $(jquery object), [dom-object], etc.

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

Als je het niet nodig hebt om geanimeerd te zijn, gebruik dan:

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

Hoe te gebruiken:

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

Notitie: #innerItem kan overal binnen zijn #overflow_div. Het hoeft niet echt een direct kind te zijn.

Getest in Firefox (23) en Chrome (28).

Als u de hele pagina wilt doorbladeren, controleert u deze vraag.


120
2017-09-21 01:24



Ik heb het antwoord van Glenn Moss aangepast om rekening te houden met het feit dat overflow div misschien niet bovenaan de pagina staat.

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

Ik gebruikte dit in een Google Maps-app met een responsieve sjabloon. Bij een resolutie> 800px stond de lijst aan de linkerkant van de kaart. Bij een resolutie <800 lag de lijst onder de kaart.


26
2018-02-15 21:47



De bovenstaande antwoorden plaatsen het binnenelement bovenaan het overloopelement, zelfs als dit zichtbaar is in het overloopelement. Ik wilde dat niet, dus heb ik het aangepast om de schuifpositie niet te veranderen als het element in beeld is.

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;
};

5
2018-06-28 08:49



Nadat ik er heel lang mee heb gespeeld, heb ik dit bedacht:

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

en ik noem het zo

$("#basketListGridHolder").scrollTo('tr[data-uid="' + basketID + '"]');

0
2018-03-31 21:15



Ik schrijf deze 2 functies om mijn leven gemakkelijker te maken:

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);
}

En gebruik ze:

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

0
2018-04-18 03:49