2010-02-27 5 views
128

Tengo 20 elementos de lista dentro de un div que solo pueden mostrar 5 a la vez. ¿Cuál es una buena manera de desplazarse al elemento n.º 10 y luego al elemento n.º 20? Sé la altura de todos los artículos.¿Cómo me desplazo a un elemento dentro de una Div desbordada?

El plugin scrollTo hace esto, pero su fuente no es súper fácil de entender sin entrar realmente en ella. No quiero usar este complemento.

Digamos que tengo una función que toma 2 elementos $parentDiv, $innerListItem, ni tampoco $innerListItem.offset().top$innerListItem.positon().top me da la correcta para scrollTop $ parentDiv.

+0

Se eliminó la respuesta debido a su actualización. Pero créanme, habiendo tenido esta misma actitud antes, hay muchas peculiaridades del navegador con posición y márgenes, etc ... el plugin es una ruta mucho más simple y consume menos tiempo, y solo 3k ** antes de ** GZip. –

+1

Use el plugin scrollTo de todos modos. No es dificil. '$ (" # contenedor "). scrollTo (destino, duración, opciones)'. Target es solo un '# anclaje. Hecho. –

+0

parece que debería haber conocimiento para hacer esto sin un complemento. mañana comenzaré a leer la fuente – mkoryak

Respuesta

196

El $innerListItem.position().top es realmente relativo al .scrollTop() de su primer antepasado posicionado. Entonces, la forma de calcular el valor correcto de $parentDiv.scrollTop() es comenzar asegurándose de que $parentDiv esté posicionado. Si aún no tiene un position explícito, use position: relative. Los elementos $innerListItem y todos sus antecesores hasta $parentDiv no necesitan tener una posición explícita. Ahora puede desplazarse a la $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); 
+0

Gracias. Esto me ayudó mucho. – Taher

+0

Gracias ... salvó mi día – Madhu

26

He ajustado respuesta Glen Moss' para tener en cuenta el hecho de que div desbordamiento podría no ser en la parte superior de la página.

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

Estaba usando esto en una aplicación de Google Maps con una plantilla receptiva. En resolución> 800 px, la lista estaba en el lado izquierdo del mapa. En la resolución < 800, la lista estaba debajo del mapa.

+0

Gracias, esto funcionó muy bien para mí cuando los otros no. –

110

Este es mi propio plug-in (posicionará el elemento en la parte superior de la la lista Especialmente para overflow-y : auto puede no funcionar con overflow-x..!):

NOTA: elem es el selector de HTML de un elemento que la página se desplazará a. Cualquier cosa soportada por jQuery, como: #myid, div.myclass, $(jquery object), [objeto DOM], etc.

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

Si no lo necesita para ser animado, a continuación, utilizar:

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

Cómo utilizar:

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

Nota: #innerItem puede estar en cualquier lugar dentro de #overflow_div. Realmente no tiene que ser un niño directo.

Probado en Firefox (23) y Chrome (28).

Si desea desplazarse por la página completa, ver this question.

+1

¡Solo quiero agradecerle por esto, funciona como un regalo! – Piercy

+0

Me alegra oír eso. Gracias – lepe

+1

por cierto hay algún plugin como http://demos.flesler.com/jquery/scrollTo/ – andi

0

Después de jugar con él por un tiempo muy largo, esto es lo que ocurrió:

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

y lo llamo como éste

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

Las respuestas anteriores posicionará el elemento interno en la parte superior del elemento de desbordamiento, incluso si está a la vista dentro del elemento de desbordamiento. No quería eso, así que lo modifiqué para no cambiar la posición de desplazamiento si el elemento está a la 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; 
}; 
+0

¡Esto me ayudó! Ver https://stackoverflow.com/questions/48283932/incorrect-up-down-scrolling-on-scrolltop-animation –

Cuestiones relacionadas