jquery - examples - ¿Cómo me desplazo a un elemento dentro de una Div desbordada?
jquery selector (6)
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.
El complemento scrollTo
hace esto, pero su fuente no es muy 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 $innerListItem.offset().top
ni $innerListItem.positon().top
me da el scrollTop correcto para $ parentDiv.
Ajusté la respuesta de Glenn Moss para explicar el hecho de que el desbordamiento div podría no estar 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.
Después de jugar con él durante mucho tiempo, esto es lo que se me ocurrió:
jQuery.fn.scrollTo = function (elem) {
var b = $(elem);
this.scrollTop(b.position().top + b.height() - this.height());
};
y lo llamo así
$("#basketListGridHolder").scrollTo(''tr[data-uid="'' + basketID + ''"]'');
El $innerListItem.position().top
es en realidad relativo al .scrollTop()
de su primer ancestro posicionado. Entonces, la forma de calcular el $parentDiv.scrollTop()
correcto $parentDiv.scrollTop()
es comenzar asegurándose de que $parentDiv
esté ubicado. Si aún no tiene una position
explícita, use position: relative
. Los elementos $innerListItem
y todos sus antecesores hasta $parentDiv
necesitan tener una posición explícita. Ahora puede desplazarse al $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);
Escribo estas 2 funciones para hacer mi vida más fácil:
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);
}
Y úsalas:
scrollToTop($innerListItem, $parentDiv, 200);
// or
scrollToCenter($innerListItem, $parentDiv, 200);
Este es mi propio complemento (colocará el elemento en la parte superior de la lista. Especialmente para overflow-y : auto
. Puede que no funcione con overflow-x
!):
NOTA : elem
es el selector de HTML de un elemento al que se desplazará la página. Todo lo que admite 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 necesita que esté animado, use:
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 toda la página, consulte esta pregunta .
Las respuestas anteriores colocarán 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;
};