¿Cómo desplazarse al principio de la página con JavaScript / jQuery?

159

¿Hay alguna manera de controlar el desplazamiento del navegador con JavaScript / jQuery?

Cuando desplazo mi página hasta la mitad, luego acciono una recarga, quiero que la página vaya a la parte superior, pero en su lugar trata de encontrar la última posición de desplazamiento. Entonces hice esto:

$('document').ready(function() {
   $(window).scrollTop(0);
});

Pero sin suerte.

EDITAR :

Así que ambas respuestas funcionaron cuando las llamo después de que se carga la página. Gracias. Sin embargo, si solo actualizo la página, parece que el navegador calcula y se desplaza a su posición de desplazamiento anterior DESPUÉS del .readyevento (también probé la función onload () del cuerpo).

Entonces, el seguimiento es, ¿hay alguna manera de PREVENIR que el navegador se desplace a su posición anterior o volver a desplazarse a la parte superior DESPUÉS de que haga lo suyo?

Yarin
fuente
1
¿Qué sucede cuando lo haces desde $ (window) .load ()?
mpdonadio
2
@ MPD- Excelente idea! ... pero solo lo intenté y el ajuste de desplazamiento todavía ocurre después de eso. Sin embargo, gracias por el consejo, en realidad ayuda con otra pregunta mía: stackoverflow.com/questions/4210829/… . Si quieres responder esa pregunta, te daré algunos comentarios.
Yarin
@Yarin Lo siento, tuviste que esperar 9 años para esto. Necesita establecer el historial.scrollRestoration antes de intentar desplazarse. Mira mi respuesta.
RayLoveless

Respuestas:

17

Wow, llego 9 años tarde a esta pregunta. Aqui tienes:

Agregue este código a su carga.

// This prevents the page from scrolling down to where it was previously.
if ('scrollRestoration' in history) {
    history.scrollRestoration = 'manual';
}
// This is needed if the user scrolls down during page load and you want to make sure the page is scrolled to the top once it's fully loaded. This has Cross-browser support.
window.scrollTo(0,0);

history.scrollRestoration Soporte del navegador:

Chrome: compatible (desde 46)

Firefox: compatible (desde 46)

IE / Edge: no compatible (aún ..)

Opera: compatible (desde 33)

Safari: compatible

Para IE / Edge si desea volver a desplazarse hacia la parte superior DESPUÉS de que se desplaza automáticamente hacia abajo, esto funcionó para mí:

var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
var isEdge = /Edge/.test(navigator.userAgent);
if(isIE11 || isEdge) {
    setTimeout(function(){ window.scrollTo(0, 0); }, 300);  // adjust time according to your page. The better solution would be to possibly tie into some event and trigger once the autoscrolling goes to the top.
} 
RayLoveless
fuente
Gracias @RayLoveless: desafortunadamente, esto no es compatible con los navegadores MS (por supuesto). Ver caniuse.com/#feat=mdn-api_history_scrollrestoration y developer.mozilla.org/de/docs/Web/API/…
Yarin el
@Yarin, buen punto. Actualicé mi publicación. Eso responde tu pregunta?
RayLoveless
312

Cross-browser, solución pura de JavaScript:

document.body.scrollTop = document.documentElement.scrollTop = 0;
Niet the Dark Absol
fuente
3
Como estás usando jQuery, puedes probar esto:$(window).one("scroll",function() { /* the code from my answer here */ });
Niet the Dark Absol
Para que esto funcione en mis navegadores cruzados IE / Chrome / FF, debo combinar la respuesta Niet Dark Absol y la respuesta user113716 (usando el tiempo de espera).
Panini Luncher
No funcionó en CentOS 6.7 con FF 45.1.0. Lo envolví en un documento listo para estar seguro.
Brandon Elliott
Solo quiero señalar que, a partir de mis pruebas (en las versiones modernas / 2018 de Chrome incluidas), esta solución funciona de manera más confiable
mattLummus
Esto no "PREVIENE que el navegador se desplace a su posición anterior". Mira mi respuesta.
RayLoveless
85

Usted casi lo consiguió - que necesita para establecer el scrollTopsobre body, no window:

$(function() {
   $('body').scrollTop(0);
});

EDITAR:

Tal vez pueda agregar un ancla en blanco en la parte superior de la página:

$(function() {
   $('<a name="top"/>').insertBefore($('body').children().eq(0));
   window.location.hash = 'top';
});
Jacob Relkin
fuente
3
Intenté esto hoy y no funcionó en FF16. Usando JS puro, visto más abajo en esta página, en su lugar: document.body.scrollTop = document.documentElement.scrollTop = 0;
Gigi2m02
2
El código anterior funcionará correctamente en los navegadores modernos como FF, Chrome, pero no funcionará en IE8 y a continuación, intente agregar ambos, 'html','body'ya que los navegadores modernos se desplazarán según el cuerpo, pero IE8 y abajo solo se desplazarán con 'html', 'cuerpo'
Rajesh
17

¿Hay alguna manera de PREVENIR que el navegador se desplace a su posición anterior o volver a desplazarse a la parte superior DESPUÉS de que haga lo suyo?

La siguiente solución jquery funciona para mí:

$(window).unload(function() {
    $('body').scrollTop(0);
});
Mate
fuente
sí, desplazarse hacia arriba antes de la actualización
Morgan T.
No es completamente cruzado, pero aún funciona para la mayoría. Cuando se combina con algunas de las otras respuestas, esta es una buena adición
Brad Decker
16

Aquí hay una versión de desplazamiento animado JavaScript puro para no-jQuery'ers: D

var stepTime = 20;
var docBody = document.body;
var focElem = document.documentElement;

var scrollAnimationStep = function (initPos, stepAmount) {
    var newPos = initPos - stepAmount > 0 ? initPos - stepAmount : 0;

    docBody.scrollTop = focElem.scrollTop = newPos;

    newPos && setTimeout(function () {
        scrollAnimationStep(newPos, stepAmount);
    }, stepTime);
}

var scrollTopAnimated = function (speed) {
    var topOffset = docBody.scrollTop || focElem.scrollTop;
    var stepAmount = topOffset;

    speed && (stepAmount = (topOffset * stepTime)/speed);

    scrollAnimationStep(topOffset, stepAmount);
};

Y entonces:

<button onclick="scrollTopAnimated(1000)">Scroll Top</button>
ulfryk
fuente
1
Frio. Sin embargo, preferiría en requestAnimationSteplugar de setTimeout. Además, no responde la pregunta de OP.
Quentin Roy
implementado esto en Angular. Funciona de maravilla. Gracias
Ahmad
12

ACTUALIZAR

Ir a la parte superior de la página con un efecto de desplazamiento es un poco más fácil en JavaScript ahora con:

https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll

window.scroll({
 top: 0, 
 left: 0, 
 behavior: 'smooth' 
});

PRECAUCIÓN

Hemos estado usando esto en nuestros proyectos más recientes, pero acabo de revisar el documento de Mozilla en este momento mientras actualizo mi respuesta y creo que se ha actualizado. En este momento el método es window.scroll(x-coord, y-coord)y no menciona ni muestra ejemplos que utilizan el objectparámetro donde se puede establecer el behaviora smooth. Acabo de probar el código y todavía funciona en Chrome y Firefox y el parámetro objeto todavía está en la especificación .

Así que use esto con precaución o puede usar este Polyfill . Aparte de desplazarse a la parte superior, esta polyfill también se ocupa de otros métodos: window.scrollBy, element.scrollIntoView, etc.


ANTIGUA RESPUESTA

Esta es nuestra javascriptimplementación de vainilla . Tiene un efecto de alivio simple para que el usuario no se sorprenda después de hacer clic en el botón Arriba .

Es muy pequeño y se vuelve aún más pequeño cuando se minifica. Los desarrolladores que buscan una alternativa al método jquery pero quieren los mismos resultados pueden intentarlo.

JS

document.querySelector("#to-top").addEventListener("click", function(){

    var toTopInterval = setInterval(function(){

        var supportedScrollTop = document.body.scrollTop > 0 ? document.body : document.documentElement;

        if (supportedScrollTop.scrollTop > 0) {
            supportedScrollTop.scrollTop = supportedScrollTop.scrollTop - 50;
        }

        if (supportedScrollTop.scrollTop < 1) {
            clearInterval(toTopInterval);
        }

    }, 10);

},false);

HTML

<button id="to-top">To Top</button>

¡Salud!

Jo E.
fuente
8

Esto funciona para mi:

window.onload = function() {
    // short timeout
    setTimeout(function() {
        $(document.body).scrollTop(0);
    }, 15);
};

Utiliza un corto setTimeoutdentro del onloadpara dar al navegador la oportunidad de hacer el desplazamiento.

usuario113716
fuente
Para que esto funcione en mis navegadores cruzados IE / Chrome / FF, debo combinar la respuesta Niet Dark Absol y la respuesta user113716 (usando el tiempo de espera).
Panini Luncher
@Panini: su sugerencia funciona para mí en Chrome / FF, pero no en IE11.
EML
8

Puedes usar con jQuery

jQuery(window).load(function(){

    jQuery("html,body").animate({scrollTop: 100}, 1000);

});
Chanderkesh Kumar
fuente
Esto es básicamente lo que FINALMENTE encontré que funcionaba en CentOS 6.7 usando FF 45.1.0. Mi versión ligeramente diferente (envuelta en una función de carga de ventana) es: $ ("html, body"). Animate ({scrollTop: 0}, 1);
Brandon Elliott
6

Use la siguiente función

window.scrollTo(xpos, ypos)

Aquí se requiere xpos. La coordenada para desplazarse, a lo largo del eje x (horizontal), en píxeles

Ypos también es obligatorio. La coordenada para desplazarse, a lo largo del eje y (vertical), en píxeles

Shoaib Quraishi
fuente
5
$(function() {
    // the element inside of which we want to scroll
        var $elem = $('#content');

        // show the buttons
    $('#nav_up').fadeIn('slow');
    $('#nav_down').fadeIn('slow');  

        // whenever we scroll fade out both buttons
    $(window).bind('scrollstart', function(){
        $('#nav_up,#nav_down').stop().animate({'opacity':'0.2'});
    });
        // ... and whenever we stop scrolling fade in both buttons
    $(window).bind('scrollstop', function(){
        $('#nav_up,#nav_down').stop().animate({'opacity':'1'});
    });

        // clicking the "down" button will make the page scroll to the $elem's height
    $('#nav_down').click(
        function (e) {
            $('html, body').animate({scrollTop: $elem.height()}, 800);
        }
    );
        // clicking the "up" button will make the page scroll to the top of the page
    $('#nav_up').click(
        function (e) {
            $('html, body').animate({scrollTop: '0px'}, 800);
        }
    );
 });

Utilizar este

Ekin Ertaç
fuente
¡Agradable! ¡Funciona bien con la animación!
Sakthivel
4

El siguiente código funciona en Firefox, Chrome y Safari , pero no pude probar esto en Internet Explorer. ¿Alguien puede probarlo y luego editar mi respuesta o comentarlo?

$(document).scrollTop(0);
gran ciego
fuente
4

Mi solución Javascript pura (animada):

function gototop() {
    if (window.scrollY>0) {
        window.scrollTo(0,window.scrollY-20)
        setTimeout("gototop()",10)
    }
}

Explicación:

window.scrollY es una variable mantenida por el navegador de la cantidad de píxeles desde la parte superior por la que se ha desplazado la ventana.

window.scrollTo(x,y) es una función que desplaza la ventana una cantidad específica de píxeles en el eje xy en el eje y.

Por lo tanto, window.scrollTo(0,window.scrollY-20)mueve la página 20 píxeles hacia la parte superior.

El setTimeoutllama a la función de nuevo en 10 milisegundos para que entonces podemos moverlo otros 20 pixeles (animados), y los ifcontroles de los estados si todavía tenga que desplazarse.

Toastrackenigma
fuente
3

¿Por qué no usas algún elemento de referencia al principio de tu archivo html, como

<div id="top"></div>

y luego, cuando se carga la página, simplemente haz

$(document).ready(function(){

    top.location.href = '#top';

});

Si el navegador se desplaza después de que se active esta función, simplemente haga

$(window).load(function(){

    top.location.href = '#top';

});
arik
fuente
3
esto funcionó para mí, pero agrega el #top en la url, ¿pueden decirme cómo puedo evitar esto, pero al mismo tiempo, sin comprometer la funcionalidad?
Abbas
3

Desplazamiento entre navegadores hacia arriba:

        if($('body').scrollTop()>0){
            $('body').scrollTop(0);         //Chrome,Safari
        }else{
            if($('html').scrollTop()>0){    //IE, FF
                $('html').scrollTop(0);
            }
        } 

Desplazamiento entre navegadores a un elemento con id = div_id:

        if($('body').scrollTop()>$('#div_id').offset().top){
            $('body').scrollTop($('#div_id').offset().top);         //Chrome,Safari
        }else{
            if($('html').scrollTop()>$('#div_id').offset().top){    //IE, FF
                $('html').scrollTop($('#div_id').offset().top);
            }
        } 
Binod Kalathil
fuente
2

Para responder a su pregunta editada, puede registrar el onscrollcontrolador de la siguiente manera:

document.documentElement.onscroll = document.body.onscroll = function() {
    this.scrollTop = 0;
    this.onscroll = null;
}

Esto hará que el primer intento de desplazamiento (que probablemente sea el automático realizado por el navegador) se cancele efectivamente.

Niet the Dark Absol
fuente
Buena solución: lo intentaré
Yarin
2

Si estás en modo peculiar (gracias @Niet the Dark Absol):

document.body.scrollTop = document.documentElement.scrollTop = 0;

Si estás en modo estricto:

document.documentElement.scrollTop = 0;

No hay necesidad de jQuery aquí.


fuente
2

Esto esta funcionando:

jQuery(document).ready(function() {
     jQuery("html").animate({ scrollTop: 0 }, "fast");
});
srdjanprpa
fuente
2

En mi caso el cuerpo no funcionó:

$('body').scrollTop(0);

Pero HTML funcionó:

$('html').scrollTop(0);
Sachin Prasad
fuente
1
Agregue ambos 'html','body'como los navegadores modernos FF, Chrome se desplazará según el cuerpo, pero IE8 y debajo solo se desplazarán con'html','body'
Rajesh
2

La combinación de estos dos me ayudó. Ninguna de las otras respuestas me ayudó, ya que tenía un sidenav que no se desplazaba.

 setTimeout(function () {
        window.scroll({
                        top: 0,
                        left: 0,
                        behavior: 'smooth'
                    });

    document.body.scrollTop = document.documentElement.scrollTop = 0;

}, 15);
Shailesh Gavathe
fuente
1
var totop = $('#totop');
totop.click(function(){
 $('html, body').stop(true,true).animate({scrollTop:0}, 1000);
 return false;
});

$(window).scroll(function(){
 if ($(this).scrollTop() > 100){ 
  totop.fadeIn();
 }else{
  totop.fadeOut();
 }
});

<img id="totop" src="img/arrow_up.png" title="Click to go Up" style="display:none;position:fixed;bottom:10px;right:10px;cursor:pointer;cursor:hand;"/>
usuario3178603
fuente
1

sin animación, solo scroll(0, 0)(vanilla JS)

maxbellec
fuente
1

Si alguien está usando un diseño angular y material con sidenav. Esto lo enviará a la parte superior de la página:

let ele = document.getElementsByClassName('md-sidenav-content');
    let eleArray = <Element[]>Array.prototype.slice.call(ele);
    eleArray.map( val => {
        val.scrollTop = document.documentElement.scrollTop = 0;
    });
Helzgate
fuente
0

Seeint el hash debería hacer el trabajo. Si tiene un encabezado, puede usar

window.location.href = "#headerid";

de lo contrario, el # solo funcionará

window.location.href = "#";

Y a medida que se escribe en la URL, se mantendrá si actualiza.

De hecho, el evento no necesita JavaScript para eso si desea hacerlo en un evento onclick, simplemente debe poner un enlace alrededor de su elemento y darle # como href.

xavierm02
fuente
Por cierto, window.location no es parte del árbol, por lo que ahora se usa para esperar la carga.
xavierm02
0

Primero agregue una etiqueta de anclaje en blanco al lugar donde desea ir

<a href="#topAnchor"></a> 

Ahora agregue una función en la sección de encabezado

 function GoToTop() {
            var urllocation = location.href;
            if (urllocation.indexOf("#topAnchor") > -1) {
                window.location.hash = "topAnchor";
            } else {
                return false;
            }
        }

finalmente agregue un evento de carga a la etiqueta del cuerpo

<body onload="GoToTop()">
Satii
fuente
0

Una versión genérica que funciona para cualquier valor X e Y, y es igual que la api window.scrollTo, solo con la adición de scrollDuration.

* Una versión genérica que coincide con la API del navegador window.scrollTo **

function smoothScrollTo(x, y, scrollDuration) {
    x = Math.abs(x || 0);
    y = Math.abs(y || 0);
    scrollDuration = scrollDuration || 1500;

    var currentScrollY = window.scrollY,
        currentScrollX = window.scrollX,
        dirY = y > currentScrollY ? 1 : -1,
        dirX = x > currentScrollX ? 1 : -1,
        tick = 16.6667, // 1000 / 60
        scrollStep = Math.PI / ( scrollDuration / tick ),
        cosParameterY = currentScrollY / 2,
        cosParameterX = currentScrollX / 2,
        scrollCount = 0,
        scrollMargin;

    function step() {        
        scrollCount = scrollCount + 1;  

        if ( window.scrollX !== x ) {
            scrollMargin = cosParameterX + dirX * cosParameterX * Math.cos( scrollCount * scrollStep );
            window.scrollTo( 0, ( currentScrollX - scrollMargin ) );
        } 

        if ( window.scrollY !== y ) {
            scrollMargin = cosParameterY + dirY * cosParameterY * Math.cos( scrollCount * scrollStep );
            window.scrollTo( 0, ( currentScrollY - scrollMargin ) );
        } 

        if (window.scrollX !== x || window.scrollY !== y) {
            requestAnimationFrame(step);
        }
    }

    step();
}
jamesmfriedman
fuente
0

Recuerdo haber visto esto publicado en otro lugar (no pude encontrar dónde), pero esto funciona muy bien:

setTimeout(() => {
    window.scrollTo(0, 0);
}, 0);

Es extraño, pero la forma en que funciona se basa en la forma en que funciona la cola de pila de JavaScript. La explicación completa se encuentra aquí en la sección Cero retrasos.

La idea básica es que el tiempo setTimeoutno especifica realmente la cantidad de tiempo establecida que esperará, sino la cantidad mínima de tiempo que esperará. Entonces, cuando le dice que espere 0 ms, el navegador ejecuta todos los demás procesos en cola (como desplazar la ventana al lugar donde estuvo por última vez) y luego ejecuta la devolución de llamada.

Greyson R.
fuente
-1
 <script>
  sessionStorage.scrollDirection = 1;//create a session variable 
  var pageScroll = function() {
  window.scrollBy ({
   top: sessionStorage.scrollDirection,
   left: 0,
   behavior: 'smooth'
   });
   if($(window).scrollTop() + $(window).height() > $(document).height() - 1)
  {    
    sessionStorage.scrollDirection= Number(sessionStorage.scrollDirection )-300;
    setTimeout(pageScroll,50);//
   }
   else{
   sessionStorage.scrollDirection=Number(sessionStorage.scrollDirection )+1
   setTimeout(pageScroll,300); 
  }
};
pageScroll();
</script>
Kenrick Humber
fuente
1
Bienvenido a stackoverflow. Además del código que ha proporcionado, intente dar alguna explicación sobre por qué y cómo soluciona el problema.
jtate