Como posso determinar a direção de um evento de rolagem do jQuery?

Estou procurando algo para esse efeito:

$(window).scroll(function(event){ if (/* magic code*/ ){ // upscroll code } else { // downscroll code } }); 

Alguma ideia?

Verificar scrollTop atual versus scrollTop anterior

 var lastScrollTop = 0; $(window).scroll(function(event){ var st = $(this).scrollTop(); if (st > lastScrollTop){ // downscroll code } else { // upscroll code } lastScrollTop = st; }); 

Você pode fazer isso sem ter que acompanhar o topo de rolagem anterior, como todos os outros exemplos exigem:

 $(window).bind('mousewheel', function(event) { if (event.originalEvent.wheelDelta >= 0) { console.log('Scroll up'); } else { console.log('Scroll down'); } }); 

Eu não sou um especialista nisso, então fique à vontade para pesquisá-lo ainda mais, mas parece que quando você usa $(element).scroll , o evento que está sendo escutado é um evento ‘scroll’.

Mas se você especificamente escutar um evento mousewheel usando bind, o atributo originalEvent do parâmetro event para seu retorno de chamada conterá informações diferentes. Parte dessa informação é wheelDelta . Se for positivo, você moveu a roda do mouse para cima. Se for negativo, você moveu a roda do mouse para baixo.

Meu palpite é que os events do mousewheel serão mousewheel quando a roda do mouse girar, mesmo que a página não role; um caso no qual os events de ‘rolagem’ provavelmente não são triggersdos. Se desejar, você pode chamar event.preventDefault() na parte inferior do seu retorno de chamada para evitar que a página role, e para que você possa usar o evento mousewheel para algo diferente de uma rolagem de página, como algum tipo de funcionalidade de zoom.

Armazene o local de rolagem anterior e veja se o novo é maior ou menor que isso.

Aqui está uma maneira de evitar quaisquer variables ​​globais ( violino disponível aqui ):

 (function () { var previousScroll = 0; $(window).scroll(function(){ var currentScroll = $(this).scrollTop(); if (currentScroll > previousScroll){ alert('down'); } else { alert('up'); } previousScroll = currentScroll; }); }()); //run this anonymous function immediately 

Solução Existente

Pode haver 3 soluções desta postagem e outra resposta .

Solução 1

  var lastScrollTop = 0; $(window).on('scroll', function() { st = $(this).scrollTop(); if(st < lastScrollTop) { console.log('up 1'); } else { console.log('down 1'); } lastScrollTop = st; }); 

Solução 2

  $('body').on('DOMMouseScroll', function(e){ if(e.originalEvent.detail < 0) { console.log('up 2'); } else { console.log('down 2'); } }); 

Solução 3

  $('body').on('mousewheel', function(e){ if(e.originalEvent.wheelDelta > 0) { console.log('up 3'); } else { console.log('down 3'); } }); 

Teste de múltiplos navegadores

Eu não pude testar no Safari

chrome 42 (Win 7)

  • Solução 1
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem
  • Soltion 2
    • Up: não funciona
    • Down: não funciona
  • Solução 3
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem

Firefox 37 (Win 7)

  • Solução 1
    • Up: 20 events por 1 pergaminho
    • Abaixo: 20 events por 1 pergaminho
  • Soltion 2
    • Up: não funciona
    • Abaixo: 1 evento por 1 rolagem
  • Solução 3
    • Up: não funciona
    • Down: não funciona

IE 11 (Win 8)

  • Solução 1
    • Para cima: 10 events por 1 rolagem (efeito colateral: rolagem para baixo ocorreu por último)
    • Abaixo: 10 events por 1 rolagem
  • Soltion 2
    • Up: não funciona
    • Down: não funciona
  • Solução 3
    • Up: não funciona
    • Abaixo: 1 evento por 1 rolagem

IE 10 (Win 7)

  • Solução 1
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem
  • Soltion 2
    • Up: não funciona
    • Down: não funciona
  • Solução 3
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem

IE 9 (Win 7)

  • Solução 1
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem
  • Soltion 2
    • Up: não funciona
    • Down: não funciona
  • Solução 3
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem

IE 8 (Win 7)

  • Solução 1
    • Up: 2 ​​events por 1 rolagem (efeito colateral: rolagem para baixo ocorreu por último)
    • Abaixo: 2 a 4 events por 1 rolagem
  • Soltion 2
    • Up: não funciona
    • Down: não funciona
  • Solução 3
    • Up: 1 evento por 1 pergaminho
    • Abaixo: 1 evento por 1 rolagem

Solução combinada

Eu verifiquei que o efeito colateral do IE 11 e IE 8 é proveniente da declaração if else . Então, eu substituí-lo com if else if declaração como a seguir.

A partir do teste com vários navegadores, decidi usar a Solução 3 para navegadores comuns e a Solução 1 para o firefox e o IE 11.

Eu referi esta resposta para detectar o IE 11.

  // Detect IE version var iev=0; var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent)); var trident = !!navigator.userAgent.match(/Trident\/7.0/); var rv=navigator.userAgent.indexOf("rv:11.0"); if (ieold) iev=new Number(RegExp.$1); if (navigator.appVersion.indexOf("MSIE 10") != -1) iev=10; if (trident&&rv!=-1) iev=11; // Firefox or IE 11 if(typeof InstallTrigger !== 'undefined' || iev == 11) { var lastScrollTop = 0; $(window).on('scroll', function() { st = $(this).scrollTop(); if(st < lastScrollTop) { console.log('Up'); } else if(st > lastScrollTop) { console.log('Down'); } lastScrollTop = st; }); } // Other browsers else { $('body').on('mousewheel', function(e){ if(e.originalEvent.wheelDelta > 0) { console.log('Up'); } else if(e.originalEvent.wheelDelta < 0) { console.log('Down'); } }); } 

Eu entendo que já houve uma resposta aceita, mas queria postar o que estou usando, caso isso possa ajudar alguém. Eu recebo a direção como cliphex com o evento mousewheel mas com suporte para o Firefox. É útil fazê-lo desta forma, caso você esteja fazendo algo como a rolagem de bloqueio e não consiga obter o topo de rolagem atual.

Veja uma versão ao vivo aqui .

 $(window).on('mousewheel DOMMouseScroll', function (e) { var direction = (function () { var delta = (e.type === 'DOMMouseScroll' ? e.originalEvent.detail * -40 : e.originalEvent.wheelDelta); return delta > 0 ? 0 : 1; }()); if(direction === 1) { // scroll down } if(direction === 0) { // scroll up } }); 

Evento de Rolagem

O evento de rolagem se comporta de forma estranha em FF (ele é acionado várias vezes devido à rolagem suave), mas funciona.

Nota: O evento de rolagem é triggersdo ao arrastar a barra de rolagem, usando as teclas de cursor ou a roda do mouse.

 //creates an element to print the scroll position $("

").appendTo("body").css({ padding: "5px 7px", background: "#e9e9e9", position: "fixed", bottom: "15px", left: "35px" }); //binds the "scroll" event $(window).scroll(function (e) { var target = e.currentTarget, self = $(target), scrollTop = window.pageYOffset || target.scrollTop, lastScrollTop = self.data("lastScrollTop") || 0, scrollHeight = target.scrollHeight || document.body.scrollHeight, scrollText = ""; if (scrollTop > lastScrollTop) { scrollText = "scroll down"; } else { scrollText = "scroll up"; } $("#test").html(scrollText + "
innerHeight: " + self.innerHeight() + "
scrollHeight: " + scrollHeight + "
scrollTop: " + scrollTop + "
lastScrollTop: " + lastScrollTop); if (scrollHeight - scrollTop === self.innerHeight()) { console.log("► End of scroll"); } //saves the current scrollTop self.data("lastScrollTop", scrollTop); });


Evento de roda

Você também pode dar uma olhada no MDN, ele expõe uma grande informação sobre o evento da roda .

Nota: O evento wheel é triggersdo apenas quando se usa a roda do mouse ; teclas do cursor e arrastando a barra de rolagem não triggers o evento.

Eu li o documento e o exemplo: Ouvindo este evento no navegador
e depois de alguns testes com FF, IE, chrome, safari, acabei com este trecho:

 //creates an element to print the scroll position $("

").appendTo("body").css({ padding: "5px 7px", background: "#e9e9e9", position: "fixed", bottom: "15px", left: "15px" }); //attach the "wheel" event if it is supported, otherwise "mousewheel" event is used $("html").on(("onwheel" in document.createElement("div") ? "wheel" : "mousewheel"), function (e) { var evt = e.originalEvent || e; //this is what really matters var deltaY = evt.deltaY || (-1 / 40 * evt.wheelDelta), //wheel || mousewheel scrollTop = $(this).scrollTop() || $("body").scrollTop(), //fix safari scrollText = ""; if (deltaY > 0) { scrollText = "scroll down"; } else { scrollText = "scroll up"; } //console.log("Event: ", evt); $("#test").html(scrollText + "
clientHeight: " + this.clientHeight + "
scrollHeight: " + this.scrollHeight + "
scrollTop: " + scrollTop + "
deltaY: " + deltaY); });

Caso você queira apenas saber se você rola para cima ou para baixo usando um dispositivo de ponteiro (mouse ou track pad), você pode usar a propriedade deltaY do evento de wheel .

 $('.container').on('wheel', function(event) { if (event.originalEvent.deltaY > 0) { $('.result').append('Scrolled down!
'); } else { $('.result').append('Scrolled up!
'); } });
 .container { height: 200px; width: 400px; margin: 20px; border: 1px solid black; overflow-y: auto; } .content { height: 300px; } 
  
Scroll me!

Action:

 var tempScrollTop, currentScrollTop = 0; $(window).scroll(function(){ currentScrollTop = $("#div").scrollTop(); if (tempScrollTop > currentScrollTop ) { // upscroll code } else if (tempScrollTop < currentScrollTop ){ // downscroll code } tempScrollTop = currentScrollTop; } 

ou use a extensão mousewheel , veja aqui .

Para ignorar qualquer snap / momentum / bounce de volta na parte superior e inferior da página, aqui está uma versão modificada da resposta aceita de Josiah :

 var prevScrollTop = 0; $(window).scroll(function(event){ var scrollTop = $(this).scrollTop(); if ( scrollTop < 0 ) { scrollTop = 0; } if ( scrollTop > $('body').height() - $(window).height() ) { scrollTop = $('body').height() - $(window).height(); } if (scrollTop >= prevScrollTop && scrollTop) { // scrolling down } else { // scrolling up } prevScrollTop = scrollTop; }); 

Você pode determinar a direção do mousewhell.

 $(window).on('mousewheel DOMMouseScroll', function (e) { var delta = e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -e.originalEvent.detail; if (delta >= 0) { console.log('scroll up'); } else { console.log('scroll down'); } }); 

Eu tenho visto muitas versões de boas respostas aqui, mas parece que algumas pessoas estão tendo problemas de navegador cruzado, então esta é a minha correção.

Eu usei isso com sucesso para detectar direção em FF, IE e Chrome … Eu não testei em safari como eu uso janelas normalmente.

 $("html, body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll': function(e) { if (e.target.id == 'el') return; e.preventDefault(); e.stopPropagation(); //Determine Direction if (e.originalEvent.wheelDelta && e.originalEvent.wheelDelta >= 0) { //Up alert("up"); } else if (e.originalEvent.detail && e.originalEvent.detail < = 0) { //Up alert("up"); } else { //Down alert("down"); } } }); 

Tenha em mente que eu também uso isso para parar qualquer rolagem, então se você quiser que a rolagem ainda ocorra, você deve remover o e.preventDefault(); e.stopPropagation(); e.preventDefault(); e.stopPropagation();

Use isso para encontrar a direção de rolagem. Isso é apenas para encontrar a direção do deslocamento vertical. Suporta todos os navegadores cruzados.

  var scrollableElement = document.getElementById('scrollableElement'); scrollableElement.addEventListener('wheel', findScrollDirectionOtherBrowsers); function findScrollDirectionOtherBrowsers(event){ var delta; if (event.wheelDelta){ delta = event.wheelDelta; }else{ delta = -1 * event.deltaY; } if (delta < 0){ console.log("DOWN"); }else if (delta > 0){ console.log("UP"); } } 

Exemplo

estoque um incremento no .data () do elemento rolado, então você será capaz de testar o número de vezes que a rolagem atingiu o topo.

Você pode usar a opção de rolagem e roda do mouse para rastrear o movimento para cima e para baixo de uma só vez.

  $('body').bind('scroll mousewheel', function(event) { if (event.originalEvent.wheelDelta >= 0) { console.log('moving down'); } else { console.log('moving up'); } }); 

Você pode replace ‘body’ por (window) também.

Para aqueles que têm problemas com rolagem elástica, por favor, use esta resposta

Como detectar a direção de rolagem

no .data() do elemento, você pode armazenar um JSON e testar valores para iniciar events

 { top : 1, first_top_event: function(){ ...}, second_top_event: function(){ ...}, third_top_event: function(){ ...}, scroll_down_event1: function(){ ...}, scroll_down_event2: function(){ ...} } 

Essa é uma detecção simples e fácil para quando o usuário rola para longe da parte superior da página e quando retorna ao topo.

 $(window).scroll(function() { if($(window).scrollTop() > 0) { // User has scrolled } else { // User at top of page } }); 

Essa é uma solução ideal para detectar a direção exatamente quando o usuário finaliza a rolagem.

 var currentScrollTop = 0 ; $(window).bind('scroll', function () { scrollTop = $(this).scrollTop(); clearTimeout($.data(this, 'scrollTimer')); $.data(this, 'scrollTimer', setTimeout(function() { if(scrollTop > currentScrollTop){ // downscroll code $('.mfb-component--bl').addClass('mfbHide'); }else{ // upscroll code $('.mfb-component--bl').removeClass('mfbHide'); } currentScrollTop = scrollTop; }, 250)); }); 

Mantenha super simples:

jQuery Event Listener Way:

 $(window).on('wheel', function(){ whichDirection(event); }); 

Vanilla JavaScript Event Listener Way:

 if(window.addEventListener){ addEventListener('wheel', whichDirection, false); } else if (window.attachEvent) { attachEvent('wheel', whichDirection, false); } 

Função permanece o mesmo:

 function whichDirection(event){ console.log(event + ' WheelEvent has all kinds of good stuff to work with'); var scrollDirection = event.deltaY; if(scrollDirection === 1){ console.log('meet me at the club, going down', scrollDirection); } else if(scrollDirection === -1) { console.log('Going up, on a tuesday', scrollDirection); } } 

Eu escrevi um post mais profundo sobre isso aqui

Você deveria tentar isso

 var scrl $(window).scroll(function(){ if($(window).scrollTop() < scrl){ //some code while previous scroll }else{ if($(window).scrollTop() > 200){ //scroll while downward }else{//scroll while downward after some specific height } } scrl = $(window).scrollTop(); });