Obter eventos de roda do mouse no jQuery?

130

Existe uma maneira de obter os eventos da roda do mouse (sem falar sobre scrolleventos) no jQuery?

thejh
fonte
1
Uma pesquisa rápida apareceu este plugin que pode ajudar.
22411 Jerad Rose
Esta solução funciona para mim: stackoverflow.com/questions/7154967/jquery-detect-scrolldown
Bertie
@thejh postou uma nova resposta sobre isso com eventos DOM3: stackoverflow.com/a/24707712/2256325
Sergio
Apenas uma nota sobre isso. Se você está apenas querendo detectar alterações em uma entrada, e não é detectar alterações via a roda do mouse, tente$(el).on('input', ...
rybo111

Respostas:

46

Há um plugin que detecta a roda do mouse para cima / baixo e a velocidade em uma região.

Darin Dimitrov
fonte
35
plugar? vamos lá .. verifique a resposta abaixo você pode fazê-lo sem
201
$(document).ready(function(){
    $('#foo').bind('mousewheel', function(e){
        if(e.originalEvent.wheelDelta /120 > 0) {
            console.log('scrolling up !');
        }
        else{
            console.log('scrolling down !');
        }
    });
});
mahdi shahbazi
fonte
51
O DOMMouseScrollevento é usado no FF, então você tem que ouvir em ambos .bind('DOMMouseScroll mousewheel') {evetns developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/...
mrzmyr
9
e.originalEvent.wheelDeltaé indefinido em FF23
hofnarwillie
26
Você não precisa dividir por 120, é inútil desperdício de cpu
venimus
6
deve ter sido a melhor resposta
2
Mas enfim, por que você gostaria de dividir por 120? O que é tão constante? (Você não tem que, como venimus apontou.)
mshthn
145

Vinculado a ambos mousewheele DOMMouseScrollacabou funcionando muito bem para mim:

$(window).bind('mousewheel DOMMouseScroll', function(event){
    if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
        // scroll up
    }
    else {
        // scroll down
    }
});

Este método está funcionando no IE9 +, Chrome 33 e Firefox 27.


Editar - Mar 2016

Decidi revisitar esse problema, já faz um tempo. A página MDN para o evento de rolagem tem uma ótima maneira de recuperar a posição de rolagem usada requestAnimationFrame, o que é altamente preferível ao meu método de detecção anterior. Modifiquei o código para oferecer melhor compatibilidade, além da direção e posição da rolagem:

(function() {
  var supportOffset = window.pageYOffset !== undefined,
    lastKnownPos = 0,
    ticking = false,
    scrollDir,
    currYPos;

  function doSomething(scrollPos, scrollDir) {
    // Your code goes here...
    console.log('scroll pos: ' + scrollPos + ' | scroll dir: ' + scrollDir);
  }

  window.addEventListener('wheel', function(e) {
    currYPos = supportOffset ? window.pageYOffset : document.body.scrollTop;
    scrollDir = lastKnownPos > currYPos ? 'up' : 'down';
    lastKnownPos = currYPos;

    if (!ticking) {
      window.requestAnimationFrame(function() {
        doSomething(lastKnownPos, scrollDir);
        ticking = false;
      });
    }
    ticking = true;
  });
})();

Veja o Pen Vanilla JS Scroll Tracking de Jesse Dupuy ( @ blindside85 ) no CodePen .

Este código está atualmente trabalhando em Chrome v50, Firefox v44, Safari v9, and IE9+

Referências:

Jesse Dupuy
fonte
Isso funcionou melhor para mim. No entanto, esse script é executado por "clique" da roda de rolagem. Isso pode ser impressionante para alguns scripts usarem. Existe uma maneira de tratar cada evento de rolagem como uma instância, em vez de executar o script por clique na roda de rolagem?
invoque 28/05
Nada de especial. Pelo que vi, muitas pessoas evitarão lidar com o rastreamento de rolagem ou usarão um temporizador (por exemplo, verifique a posição do usuário na página a cada x milissegundos, etc). Se existe uma solução com melhor desempenho por aí, eu definitivamente quero saber sobre isso!
Jesse Dupuy
1
Eu encontrei uma maneira de fazer isso: stackoverflow.com/questions/23919035/…
invoc
1
Obrigado pela atualização. Você pode copiar seu código em sua resposta? Nunca se sabe se o codepen pode cair algum dia. Já aconteceu antes.
JDB ainda se lembra de Monica
2
@JesseDupuy, gostaria de dar uma resposta positiva a essa resposta, mas sua versão atualizada não funcionará se o documento corresponder à visualização ("width: 100vh; height: 100vh") ou tiver "overflow: hidden;". "window.addEventListener ('scroll', callback)" não é a resposta correta para "window.addEventListener ('mousewheel', callback)".
Daniel
45

A partir de agora em 2017, você pode escrever

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

  // deltaY obviously records vertical scroll, deltaX and deltaZ exist too
  if(event.originalEvent.deltaY < 0){
    // wheeled up
  }
  else {
    // wheeled down
  }
});

Funciona com o Firefox 51, Chrome 56, IE9 + atual

Louis Ameline
fonte
37

As respostas que falam sobre o evento "mousewheel" referem-se a um evento descontinuado. O evento padrão é simplesmente "roda". Consulte https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel

Brian Di Palma
fonte
20
Eu tentei estas e descobri: "wheel" funciona no Firefox e IE, mas não no Chrome. "mousewheel" funciona no Chrome e IE, mas não no Firefox. "DOMMouseScroll" funciona apenas no Firefox.
Curtis Yallop
1
Uau, isso me salvou muito tempo. Obrigado!
gustavohenke
3
Looks como o Chrome adicionou suporte para "roda" em agosto de 2013: code.google.com/p/chromium/issues/detail?id=227454
rstackhouse
2
O Safari ainda não suporta o evento wheel.
Thayne
Como a documentação diz: wheelevento é apoiado em Edge não IEque não é a mesma coisa. CanIuse
Alex
16

Isso funcionou para mim :)

 //Firefox
 $('#elem').bind('DOMMouseScroll', function(e){
     if(e.originalEvent.detail > 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

 //IE, Opera, Safari
 $('#elem').bind('mousewheel', function(e){
     if(e.originalEvent.wheelDelta < 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

de stackoverflow

Anjith KP
fonte
14

Aqui está uma solução de baunilha. Pode ser usado no jQuery se o evento passado para a função é o event.originalEventque o jQuery disponibiliza como propriedade do evento jQuery. Ou, se dentro da callbackfunção abaixo, adicionamos antes da primeira linha:event = event.originalEvent; .

Esse código normaliza a velocidade / quantidade da roda e é positivo para o que seria uma rolagem para a frente em um mouse típico e negativo em um movimento da roda para trás do mouse.

Demonstração: http://jsfiddle.net/BXhzD/

var wheel = document.getElementById('wheel');

function report(ammout) {
    wheel.innerHTML = 'wheel ammout: ' + ammout;
}

function callback(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    report(normalized);
}

var event = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
window.addEventListener(event, callback);

Há também um plug-in para jQuery, que é mais detalhado no código e um pouco mais de açúcar: https://github.com/brandonaaron/jquery-mousewheel

Sergio
fonte
8

Isso está funcionando nas versões mais recentes do IE, Firefox e Chrome.

$(document).ready(function(){
        $('#whole').bind('DOMMouseScroll mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
                alert("up");
            }
            else{
                alert("down");
            }
        });
    });
futuredayv
fonte
5

Eu estava preso nesta questão hoje e achei que esse código está funcionando bem para mim

$('#content').on('mousewheel', function(event) {
    //console.log(event.deltaX, event.deltaY, event.deltaFactor);
    if(event.deltaY > 0) {
      console.log('scroll up');
    } else {
      console.log('scroll down');
    }
});
Prafull Sharma
fonte
4

use este código

 knob.bind('mousewheel', function(e){  
 if(e.originalEvent.wheelDelta < 0) {
    moveKnob('down');
  } else {
    moveKnob('up');
 }
  return false;
});
Bal mukund kumar
fonte
0

minha combinação fica assim. desaparece e desaparece em cada rolagem para baixo / para cima. caso contrário, você precisará rolar até o cabeçalho para inserir o cabeçalho.

var header = $("#header");
$('#content-container').bind('mousewheel', function(e){
    if(e.originalEvent.wheelDelta > 0) {
        if (header.data('faded')) {
            header.data('faded', 0).stop(true).fadeTo(800, 1);
        }
    }
    else{
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);
    }
});

o acima não é otimizado para touch / mobile, acho que esse é o melhor para todos os dispositivos móveis:

var iScrollPos = 0;
var header = $("#header");
$('#content-container').scroll(function () {

    var iCurScrollPos = $(this).scrollTop();
    if (iCurScrollPos > iScrollPos) {
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);

    } else {
        //Scrolling Up
        if (header.data('faded')) {
            header.data('faded', 0).stop(true).fadeTo(800, 1);
        }
    }
    iScrollPos = iCurScrollPos;

});
Thomas Hartmann
fonte
0

O plugin que o @DarinDimitrov postou jquery-mousewheel, está quebrado com o jQuery 3+ . Seria mais aconselhável usar o jquery-wheelque funciona com o jQuery 3+.

Se você não deseja seguir a rota do jQuery, o MDN recomenda o uso do mousewheelevento, pois ele não é padrão e não é suportado em muitos lugares. Em vez disso, diz que você deve usar o wheelevento à medida que obtém muito mais especificidade sobre exatamente quais são os valores que você está recebendo. É suportado pela maioria dos principais navegadores.

Coburn
fonte
0

Se você estiver usando o plug-in jquery mousewheel mencionado , que tal usar o segundo argumento da função manipulador de eventos - delta:

$('#my-element').on('mousewheel', function(event, delta) {
    if(delta > 0) {
    console.log('scroll up');
    } 
    else {
    console.log('scroll down');
    }
});
Mojo
fonte
-3

Eu tive o mesmo problema recentemente, onde $(window).mousewheelestava retornandoundefined

O que eu fiz foi $(window).on('mousewheel', function() {});

Além de processá-lo, estou usando:

function (event) {
    var direction = null,
        key;

    if (event.type === 'mousewheel') {
        if (yourFunctionForGetMouseWheelDirection(event) > 0) {
            direction = 'up';
        } else {
            direction = 'down';
        }
    }
}
Szymon Toda
fonte
Você não disse o que tem newUtilities.getMouseWheelDirection #
ccsakuweb
Está fora do escopo desta questão. Portanto, não é copiar colar site.
Szymon Toda