javascript - react - ScrollIntoView() causando que toda la página se mueva
scrollintoview offset (8)
El complemento jQuery scrollintoview()
aumenta la usabilidad
En lugar de la implementación predeterminada de DOM, puedes usar un complemento que anima el movimiento y no tiene ningún efecto no deseado. Esta es la forma más sencilla de usarlo con los valores predeterminados:
$("yourTargetLiSelector").scrollintoview();
De todos modos, dirígete a esta publicación del blog donde puedes leer todos los detalles y eventualmente llegarás al código fuente de GitHub del complemento.
Este complemento busca automáticamente el elemento ancestral desplazable más cercano y lo desplaza para que el elemento seleccionado se encuentre dentro de su puerto de vista visible. Si el elemento ya está en el puerto de vista, no hace nada, por supuesto.
Estoy usando ScrollIntoView () para desplazar el elemento resaltado en una lista a la vista. Cuando me desplazo hacia abajo, ScrollIntoView (falso) funciona perfectamente. Pero cuando me desplazo hacia arriba, ScrollIntoView (verdadero) hace que toda la página se mueva un poco, lo que creo que está pensado. ¿Hay alguna forma de evitar el movimiento completo de la página al usar ScrollIntoView (verdadero)?
Aquí está la estructura de mi página -
#listOfDivs {
position:fixed;
top:100px;
width: 300px;
height: 300px;
overflow-y: scroll;
}
<div="container">
<div="content">
<div id="listOfDivs">
<div id="item1"> </div>
<div id="item2"> </div>
<div id="itemn"> </div>
</div>
</div>
</div>
listOfDivs viene de la llamada ajax. Utilizando safari móvil.
Gracias por su ayuda por adelantado!
He agregado una forma de mostrar el comportamiento importante de ScrollIntoView - jsfiddle.net/LEqjm/258 [debería ser un comentario pero no tengo suficiente reputación]
$("ul").click(function() {
var target = document.getElementById("target");
if ($(''#scrollTop'').attr(''checked'')) {
target.parentNode.scrollTop = target.offsetTop;
} else {
target.scrollIntoView(!0);
}
});
Juegue con scrollIntoViewIfNeeded()
... asegúrese de que sea compatible con el navegador.
Lo arreglamos con:
element.scrollIntoView({ behavior: ''smooth'', block: ''nearest'', inline: ''start'' })
Consulte: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Puedes usar scrollTop
lugar de scrollIntoView()
:
var target = document.getElementById("target");
target.parentNode.scrollTop = target.offsetTop;
jsFiddle: http://jsfiddle.net/LEqjm/
Si hay más de un elemento desplazable que desea desplazar, deberá cambiar la scrollTop
de scrollTop
de cada uno individualmente, en función de las offsetTop
de offsetTop
de los elementos intermedios. Esto debería darle un control detallado para evitar el problema que está teniendo.
EDIT: offsetTop no es necesariamente relativo al elemento padre, es relativo al primer antepasado posicionado. Si el elemento padre no está posicionado (relativo, absoluto o fijo), es posible que deba cambiar la segunda línea a:
target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop;
Tuve el mismo problema, lo solucioné eliminando la transform:translateY
CSS que coloqué en el footer
de footer
de la página.
Usando la idea de Brilliant, aquí hay una solución que solo se desplaza (verticalmente) si el elemento NO está actualmente visible. La idea es obtener el cuadro delimitador de la ventana gráfica y el elemento que se mostrará en el espacio de coordenadas de la ventana del navegador. Compruebe si está visible y, si no, desplácese por la distancia requerida para que el elemento se muestre en la parte superior o inferior de la ventana.
function ensure_visible(element_id)
{
// adjust these two to match your HTML hierarchy
var element_to_show = document.getElementById(element_id);
var scrolling_parent = element_to_show.parentElement;
var top = parseInt(scrolling_parent.getBoundingClientRect().top);
var bot = parseInt(scrolling_parent.getBoundingClientRect().bottom);
var now_top = parseInt(element_to_show.getBoundingClientRect().top);
var now_bot = parseInt(element_to_show.getBoundingClientRect().bottom);
// console.log("Element: "+now_top+";"+(now_bot)+" Viewport:"+top+";"+(bot) );
var scroll_by = 0;
if(now_top < top)
scroll_by = -(top - now_top);
else if(now_bot > bot)
scroll_by = now_bot - bot;
if(scroll_by != 0)
{
scrolling_parent.scrollTop += scroll_by; // tr.offsetTop;
}
}
var el = document.querySelector("yourElement");
window.scroll({top: el.offsetTop, behavior: ''smooth''});