Obtener eventos de rueda del mouse en jQuery?

130

¿Hay alguna manera de obtener los eventos de la rueda del mouse (sin hablar de scrolleventos) en jQuery?

thejh
fuente
1
Una búsqueda rápida mostró este complemento que puede ayudar.
Jerad Rose
@thejh publicó una nueva respuesta sobre esto con los eventos DOM3: stackoverflow.com/a/24707712/2256325
Sergio
Solo una nota sobre esto. Si solo desea detectar cambios en una entrada, y no está detectando cambios a través de la rueda del mouse, intente$(el).on('input', ...
rybo111

Respuestas:

46

Hay un complemento que detecta la rueda del mouse arriba / abajo y la velocidad sobre una región.

Darin Dimitrov
fuente
35
¿enchufar? vamos .. compruebe la respuesta a continuación, puede hacerlo sin
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
fuente
51
El DOMMouseScrollevento se usa en FF, por lo que debe escuchar en ambos .bind('DOMMouseScroll mousewheel') {eventos developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/…
mrzmyr
9
e.originalEvent.wheelDeltano está definido en FF23
hofnarwillie
26
No es necesario dividir por 120, es un desperdicio inútil de CPU
venimus
66
debe haber sido la mejor respuesta
2
Pero de todos modos, ¿por qué querrías dividirlo por 120? ¿Qué es eso constante? (No es necesario, como señaló Venimus.)
mshthn
145

Me uní a ambos mousewheely DOMMouseScrollterminé funcionando muy bien para mí:

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

Este método funciona en IE9 +, Chrome 33 y Firefox 27.


Editar - Mar 2016

Decidí revisar este problema ya que ha pasado un tiempo. La página MDN para el evento de desplazamiento tiene una excelente manera de recuperar la posición de desplazamiento que utiliza requestAnimationFrame, lo cual es muy preferible a mi método de detección anterior. Modifiqué su código para proporcionar una mejor compatibilidad además de la dirección y posición de desplazamiento:

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

Vea el seguimiento de desplazamiento de Pen Vanilla JS por Jesse Dupuy ( @ blindside85 ) en CodePen .

Este código está trabajando actualmente en Chrome v50, Firefox v44, Safari v9, and IE9+

Referencias

Jesse Dupuy
fuente
Esto funcionó mejor para mí. Sin embargo, este script se ejecuta por "clic" de la rueda de desplazamiento. Esto puede ser abrumador para algunos scripts para usar. ¿Hay alguna manera de tratar cada evento de desplazamiento como una instancia, en lugar de ejecutar el script por clic en la rueda de desplazamiento?
invitación
No especialmente. Por lo que he visto, muchas personas evitarán lidiar con el seguimiento de desplazamiento o usarán un temporizador (por ejemplo, verifique la posición del usuario en la página cada x milisegundos, etc.). Si hay una solución más eficaz, ¡definitivamente quiero saberlo!
Jesse Dupuy
1
Encontré una manera de hacer esto: stackoverflow.com/questions/23919035/…
invito el
1
Gracias por la actualización. ¿Puedes copiar tu código en tu respuesta? Nunca se sabe si codepen podría caer algún día. Ya ha sucedido antes.
JDB todavía recuerda a Monica
2
@JesseDupuy, votaría esta respuesta, pero su versión actualizada no funciona si el documento se ajusta a la vista ("ancho: 100vh; altura: 100vh") u obtiene "desbordamiento: oculto;". "window.addEventListener ('scroll', callback)" no es la respuesta correcta a "window.addEventListener ('mousewheel', callback)".
Daniel
45

A partir de ahora en 2017, puedes escribir

$(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 con Firefox 51 actual, Chrome 56, IE9 +

Louis Ameline
fuente
37

Las respuestas que hablan sobre el evento "mousewheel" se refieren a un evento en desuso. El evento estándar es simplemente "rueda". Ver https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel

Brian Di Palma
fuente
20
Probé estos y encontré: "wheel" funciona en Firefox e IE pero no en Chrome. "mousewheel" funciona en Chrome e IE pero no en Firefox. "DOMMouseScroll" solo funciona en Firefox.
Curtis Yallop
1
Whoa, esto me ahorró mucho tiempo. ¡Gracias!
gustavohenke
3
Parece que Chrome agregó soporte para "rueda" en agosto de 2013: code.google.com/p/chromium/issues/detail?id=227454
rstackhouse
2
Safari todavía no es compatible con el evento de la rueda.
Thayne
Como dice su documentación, el wheelevento no es compatible con Edge lo IEque no es lo mismo. CanIuse
Alex
16

Esto funcionó para mí :)

 //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
fuente
14

Aquí hay una solución de vainilla. Se puede usar en jQuery si el evento pasado a la función es el event.originalEventque jQuery pone a disposición como propiedad del evento jQuery. O si dentro de la callbackfunción debajo agregamos antes de la primera línea:event = event.originalEvent; .

Este código normaliza la velocidad / cantidad de la rueda y es positivo para lo que sería un desplazamiento hacia adelante en un mouse típico, y negativo en un movimiento hacia atrás de la rueda del mouse.

Demostración: 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);

También hay un complemento para jQuery, que es más detallado en el código y un poco de azúcar extra: https://github.com/brandonaaron/jquery-mousewheel

Sergio
fuente
8

Esto funciona en cada versión de IE, Firefox y 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
fuente
5

Hoy me quedé atrapado en este problema y descubrí que este código funciona bien para mí.

$('#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
fuente
4

usa este código

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

mi combinación se ve así. se desvanece y se desvanece en cada desplazamiento hacia abajo / arriba. de lo contrario, debe desplazarse hacia arriba al encabezado, para desvanecer el encabezado.

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

el anterior no está optimizado para touch / mobile, creo que este lo hace mejor para todos los móviles:

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
fuente
0

El plugin que @DarinDimitrov publicada, jquery-mousewheel, se rompe con jQuery 3+ . Sería más recomendable utilizar jquery-wheelqué funciona con jQuery 3+.

Si no desea seguir la ruta jQuery, MDN advierte altamente el uso del mousewheelevento, ya que no es estándar y no es compatible en muchos lugares. En cambio, dice que debe usar el wheelevento ya que obtiene mucha más especificidad sobre exactamente lo que significan los valores que está obteniendo. Es compatible con la mayoría de los principales navegadores.

Coburn
fuente
0

Si se utiliza mencionado jQuery plugin de la rueda del ratón , entonces ¿qué pasa a utilizar el segundo argumento de la función de controlador de eventos - delta:

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

Tengo el mismo problema recientemente donde $(window).mousewheelestaba regresandoundefined

Lo que hice fue $(window).on('mousewheel', function() {});

Además para procesarlo estoy usando:

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

    if (event.type === 'mousewheel') {
        if (yourFunctionForGetMouseWheelDirection(event) > 0) {
            direction = 'up';
        } else {
            direction = 'down';
        }
    }
}
Szymon Toda
fuente
No dijiste lo que tiene newUtilities.getMouseWheelDirection
ccsakuweb
Está fuera del alcance de esta pregunta. Entonces, no es un sitio web de copiar y pegar.
Szymon Toda