Come faccio a scorrere verso un elemento all’interno di un Div overflow?

Ho 20 voci di lista all’interno di un div che può mostrare solo 5 alla volta. Qual è un buon modo per scorrere fino all’elemento # 10 e quindi all’articolo 20? Conosco l’altezza di tutti gli oggetti.

Il plugin scrollTo fa questo, ma la sua fonte non è super facile da capire senza esserci veramente dentro. Non voglio usare questo plugin.

Diciamo che ho una funzione che prende 2 elementi $parentDiv , $innerListItem , né $innerListItem.offset().top$innerListItem.positon().top mi dà lo scrollTop corretto per $ parentDiv.

$innerListItem.position().top è in realtà relativo al .scrollTop() del suo primo antenato posizionato. Quindi il modo per calcolare il valore corretto $parentDiv.scrollTop() è iniziare assicurandosi che $parentDiv sia posizionato. Se non ha già una position esplicita, usa la position: relative . Gli elementi $innerListItem e tutti i relativi antenati fino a $parentDiv devono avere una posizione esplicita. Ora puoi scorrere fino a $innerListItem con:

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

Questo è il mio plugin (posizionerà l’elemento in cima alla lista. Specialmente per overflow-y : auto . Potrebbe non funzionare con overflow-x !):

NOTA : elem è il selettore HTML di un elemento a cui si scorre la pagina. Qualsiasi cosa supportata da jQuery, come: #myid , div.myclass , $(jquery object) , [dom object], ecc.

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

Se non ne hai bisogno per essere animato, quindi utilizzare:

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

Come usare:

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

Nota: #innerItem può essere ovunque all’interno di #overflow_div . In realtà non deve essere un bambino diretto.

Testato su Firefox (23) e Chrome (28).

Se vuoi scorrere l’intera pagina, controlla questa domanda .

Ho modificato la risposta di Glenn Moss per tenere conto del fatto che il div overflow potrebbe non essere nella parte superiore della pagina.

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

Stavo usando questo su un’applicazione google maps con un modello reattivo. In risoluzione> 800 px, l’elenco era sul lato sinistro della mappa. In risoluzione <800 l'elenco era sotto la mappa.

Le risposte di cui sopra posizioneranno l’elemento interno nella parte superiore dell’elemento di overflow anche se è visibile nell’elemento di overflow. Non volevo che così l’ho modificato per non cambiare la posizione di scorrimento se l’elemento è in vista.

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

Dopo aver giocato con lui per molto tempo, questo è quello che mi è venuto in mente:

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

e io lo chiamo così

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

Scrivo queste 2 funzioni per semplificarmi la vita:

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

E usali:

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