Detectando direção de rolagem


119

Portanto, estou tentando usar o JavaScript on scrollpara chamar uma função. Mas eu queria saber se conseguia detectar a direção do pergaminho sem usar jQuery. Se não, há alguma solução alternativa?

Eu estava pensando em apenas colocar um botão 'para cima', mas gostaria de evitar isso se pudesse.

Acabei de tentar usar este código, mas não funcionou:

if document.body.scrollTop <= 0 {
    alert ("scrolling down")
} else {
    alert ("scrolling up")
}

É o wheelDeltado evento. Bastante não cross-browser. Consulte phrogz.net/js/wheeldelta.html
marekful

1
hmmm não é bem o que estava procurando, mas agradeço sua ajuda: P Alguma outra sugestão?
dwinnbrown

Respostas:


176

Ele pode ser detectado armazenando o scrollTopvalor anterior e comparando o valor atual do scrollTop com ele.

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);

20
Seria mais seguro inicializar lastScrollTopcom pageYOffset || scrollTop em vez de assumir 0
Ed Ballot

Concordo plenamente !! Obrigado @EdBallot. Devemos inicializar o mesmo no evento window.onload.
Prateek

@Prateek Obrigado pela sua resposta, mas não está funcionando para mim ... Estou tentando 'mudar de cena' em meu webapp, que é construído usando o Tumult Hype.
dwinnbrown

Eu adicionei alguns comentários em minha resposta, por favor, verifique. Acho que você está usando "element.addEventListener".
Prateek

@Prateek ainda nada, estou com medo. Poderia ter a ver com o fato de que estou executando-o no carregamento da página? Aqui está uma captura de tela: i.imgur.com/Q0H0T4s.png
dwinnbrown

53

Maneira simples de capturar todos os eventos de rolagem (toque e roda)

window.onscroll = function(e) {
  // print "false" if direction is down and "true" if up
  console.log(this.oldScroll > this.scrollY);
  this.oldScroll = this.scrollY;
}

10
Bem-vindo ao SO. Se você adicionar uma descrição à sua resposta, isso pode ser mais útil para o OP e para outros.
Alejandro Montilla

32

Use para encontrar a direção de rolagem. Isso é apenas para encontrar a direção do rolo vertical. Suporta todos os 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;
}

Exemplo


2
Isso é bom, mas parece funcionar apenas para usar a roda de rolagem
Jonathan.Brink,

1
De webdocs MDN: Nota: Não confunda o evento de roda com o evento de rolagem. A ação padrão de um evento de roda é específica da implementação e não necessariamente despacha um evento de rolagem. Mesmo quando isso acontece, os valores delta * no evento de roda não refletem necessariamente a direção de rolagem do conteúdo. Portanto, não confie nas propriedades delta * do evento de roda para obter a direção de rolagem. Em vez disso, detecte alterações de valor de scrollLeft e scrollTop do destino no evento de rolagem. developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
battaboombattabaam

10

Você pode tentar fazer isso.

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>


isso não está funcionando bem para mim. Quando eu rolar para cima, mesmo até uma certa altura, ele aparece
Desenvolvedor

8

Este é um complemento ao que Prateek respondeu. Parece haver uma falha no código do IE, então decidi modificá-lo um pouco nada extravagante (apenas outra condição)

$('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;
});});

1
Obrigado pela sua dica ... parece estar conectado à opção "Smooth Scrolling" do IE
Kristo

5
  1. Inicialize um oldValue
  2. Obtenha o novo valor ouvindo o evento
  3. Subtraia os dois
  4. Concluir a partir do resultado
  5. Atualize oldValue com o newValue

// Inicialização

let oldValue = 0;

// Ouvindo no 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;
});

3

Você pode obter a posição da barra de rolagem usando document.documentElement.scrollTop. E então é simplesmente uma questão de compará-lo com a posição anterior.


Ok, eu ainda poderia usar isso em um site que tradicionalmente não permite a rolagem (ou seja, cabe no navegador 100% de largura e altura. Obrigado
dwinnbrown

2

Este código simples funcionaria: Verifique os resultados no console.

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);
});

1

Eu pessoalmente uso esse código para detectar a direção de rolagem em javascript ... Você só precisa definir uma variável para armazenar lastscrollvalue e usar este 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;

    }
}

0

Código simples

// 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();
}

Embora este código possa responder à pergunta, fornecer contexto adicional sobre como e / ou por que ele resolve o problema melhoraria o valor da resposta a longo prazo.
Pato Donald
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.