Detectando dirección de desplazamiento

120

Entonces estoy tratando de usar JavaScript on scrollpara llamar a una función. Pero quería saber si podía detectar la dirección del desplazamiento sin usar jQuery. Si no es así, ¿hay alguna solución?

Estaba pensando en poner un botón 'arriba', pero me gustaría evitarlo si pudiera.

Ahora acabo de intentar usar este código pero no funcionó:

if document.body.scrollTop <= 0 {
    alert ("scrolling down")
} else {
    alert ("scrolling up")
}
dwinnbrown
fuente
Es el wheelDeltadel evento. No es para varios navegadores. Ver phrogz.net/js/wheeldelta.html
marekful
1
hmmm no es exactamente lo que estaba buscando, pero agradezco su ayuda: P ¿Alguna otra sugerencia?
dwinnbrown

Respuestas:

177

Se puede detectar almacenando el scrollTopvalor anterior y comparando el valor actual de scrollTop con él.

JavaScript:

var lastScrollTop = 0;

// element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element.
element.addEventListener("scroll", function(){ // or window.addEventListener("scroll"....
   var st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
   if (st > lastScrollTop){
      // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
}, false);
Prateek
fuente
20
Sería más seguro inicializar lastScrollTopen pageYOffset || scrollTop en lugar de asumir 0
Ed Ballot
Totalmente de acuerdo !! Gracias @EdBallot. Deberíamos inicializar lo mismo en el evento window.onload.
Prateek
@Prateek Gracias por tu respuesta, pero no funciona para mí ... Estoy tratando de 'cambiar de escena' en mi aplicación web que se creó con Tumult Hype.
dwinnbrown
He agregado algunos comentarios en mi respuesta, compruébelo. Supongo que estás usando "element.addEventListener".
Prateek
@Prateek todavía nada, me temo. ¿Podría tener que ver con el hecho de que lo estoy ejecutando al cargar la página? Aquí hay una captura de pantalla: i.imgur.com/Q0H0T4s.png
dwinnbrown
53

Una forma sencilla de capturar todos los eventos de desplazamiento (toque y rueda)

window.onscroll = function(e) {
  // print "false" if direction is down and "true" if up
  console.log(this.oldScroll > this.scrollY);
  this.oldScroll = this.scrollY;
}
ES VLOG
fuente
10
Bienvenido a SO, si agrega una descripción a su respuesta, esto puede ser más útil para el OP y para otros.
Alejandro Montilla
32

Use esto para encontrar la dirección de desplazamiento. Esto es solo para encontrar la dirección del desplazamiento vertical. Admite todos los navegadores cruzados.

var scrollableElement = document.body; //document.getElementById('scrollableElement');

scrollableElement.addEventListener('wheel', checkScrollDirection);

function checkScrollDirection(event) {
  if (checkScrollDirectionIsUp(event)) {
    console.log('UP');
  } else {
    console.log('Down');
  }
}

function checkScrollDirectionIsUp(event) {
  if (event.wheelDelta) {
    return event.wheelDelta > 0;
  }
  return event.deltaY < 0;
}

Ejemplo

Vasi
fuente
2
Esto es bueno, pero solo parece funcionar para usar la rueda de desplazamiento
Jonathan.Brink
1
De MDN webdocs: Nota: No confunda el evento de rueda con el evento de desplazamiento. La acción predeterminada de un evento de rueda es específica de la implementación y no necesariamente envía un evento de desplazamiento. Incluso cuando lo hace, los valores delta * en el evento de rueda no reflejan necesariamente la dirección de desplazamiento del contenido. Por lo tanto, no confíe en las propiedades delta * del evento de rueda para obtener la dirección de desplazamiento. En su lugar, detecta cambios de valor de scrollLeft y scrollTop del objetivo en el evento de desplazamiento. developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
battaboombattabaam
10

Puedes intentar hacer esto.

function scrollDetect(){
  var lastScroll = 0;

  window.onscroll = function() {
      let currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // Get Current Scroll Value

      if (currentScroll > 0 && lastScroll <= currentScroll){
        lastScroll = currentScroll;
        document.getElementById("scrollLoc").innerHTML = "Scrolling DOWN";
      }else{
        lastScroll = currentScroll;
        document.getElementById("scrollLoc").innerHTML = "Scrolling UP";
      }
  };
}


scrollDetect();
html,body{
  height:100%;
  width:100%;
  margin:0;
  padding:0;
}

.cont{
  height:100%;
  width:100%;
}

.item{
  margin:0;
  padding:0;
  height:100%;
  width:100%;
  background: #ffad33;
}

.red{
  background: red;
}

p{
  position:fixed;
  font-size:25px;
  top:5%;
  left:5%;
}
<div class="cont">
  <div class="item"></div>
  <div class="item red"></div>
  <p id="scrollLoc">0</p>
</div>

davecar21
fuente
esto no me está funcionando bien. Cuando me desplazo hacia arriba incluso hasta cierta altura, aparece hacia abajo
Desarrollador
8

Esto es una adición a lo que ha respondido prateek.Parece haber un error en el código en IE, así que decidí modificarlo un poco nada especial (solo otra condición)

$('document').ready(function() {
var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       console.log("down")
   }
   else if(st == lastScrollTop)
   {
     //do nothing 
     //In IE this is an important condition because there seems to be some instances where the last scrollTop is equal to the new one
   }
   else {
      console.log("up")
   }
   lastScrollTop = st;
});});
Emmanual
fuente
1
Gracias por tu sugerencia ... esto parece estar relacionado con la opción "Desplazamiento suave" de IE
Kristo
5
  1. Inicializar un valor antiguo
  2. Obtenga el nuevo valor escuchando el evento
  3. Resta los dos
  4. Concluir del resultado
  5. Actualizar oldValue con newValue

// Inicialización

let oldValue = 0;

// Escuchando el evento

window.addEventListener('scroll', function(e){

    // Get the new Value
    newValue = window.pageYOffset;

    //Subtract the two and conclude
    if(oldValue - newValue < 0){
        console.log("Up");
    } else if(oldValue - newValue > 0){
        console.log("Down");
    }

    // Update the old value
    oldValue = newValue;
});
thewebjackal
fuente
3

Puede obtener la posición de la barra de desplazamiento usando document.documentElement.scrollTop. Y luego es simplemente cuestión de compararlo con la posición anterior.

Igal S.
fuente
De acuerdo, ¿podría seguir usando esto en un sitio web que tradicionalmente no permite el desplazamiento (es decir, se ajusta al 100% del ancho y la altura del navegador? Gracias
dwinnbrown
2

Este código simple funcionaría: revise la consola para ver los resultados.

let scroll_position = 0;
let scroll_direction;

window.addEventListener('scroll', function(e){
    scroll_direction = (document.body.getBoundingClientRect()).top > scroll_position ? 'up' : 'down';
    scroll_position = (document.body.getBoundingClientRect()).top;
    console.log(scroll_direction);
});
Usman Ahmed
fuente
1

Yo personalmente uso este código para detectar la dirección de desplazamiento en javascript ... Solo tienes que definir una variable para almacenar lastscrollvalue y luego usar esto if & else

let lastscrollvalue;

function headeronscroll() {

    // document on which scroll event will occur
    var a = document.querySelector('.refcontainer'); 

    if (lastscrollvalue == undefined) {

        lastscrollvalue = a.scrollTop;

        // sets lastscrollvalue
    } else if (a.scrollTop > lastscrollvalue) {

        // downscroll rules will be here
        lastscrollvalue = a.scrollTop;

    } else if (a.scrollTop < lastscrollvalue) {

        // upscroll rules will be here
        lastscrollvalue = a.scrollTop;

    }
}
VagónLobo
fuente
0

Código simple

// Events
$(document).on('mousewheel DOMMouseScroll', "element", function(e) {
    let delta = e.originalEvent.wheelDelta;
    
    if (delta > 0 || e.originalEvent.detail < 0) upScrollFunction();
    if (delta < 0 || e.originalEvent.detail > 0) donwScrollFunction();
}
Ricardo Schmidt
fuente
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre cómo y / o por qué resuelve el problema mejoraría el valor de la respuesta a largo plazo.
Donald Duck