Cómo detectar la dirección de desplazamiento

Quiero ejecutar una función cuando alguien se desplaza hacia abajo en un elemento. Algo como esto:

$('div').scrollDown(function(){ alert('down') }); $('div').scrollUp(function(){ alert('up') }); 

Pero esas funciones no existen. ¿Hay una solución a este problema? Parecen ser capaces de hacerlo. Lamentablemente, el código fuente está comprimido, así que no hay suerte allí …

¡¡Gracias!!

Logré resolverlo al final, así que si alguien está buscando la respuesta:

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

El siguiente ejemplo escuchará solo el desplazamiento de MOUSE, sin toque ni desplazamientos del panel táctil.

Utiliza jQuery.on () (A partir de jQuery 1.7, el método .on () es el método preferido para adjuntar controladores de eventos a un documento).

 $('#elem').on( 'DOMMouseScroll mousewheel', function ( event ) { if( event.originalEvent.detail > 0 || event.originalEvent.wheelDelta < 0 ) { //alternative options for wheelData: wheelDeltaX & wheelDeltaY //scroll down console.log('Down'); } else { //scroll up console.log('Up'); } //prevent page fom scrolling return false; }); 

Funciona en todos los navegadores.

violín: http://jsfiddle.net/honk1/gWnNv/7/

Este merece una actualización: hoy tenemos el evento wheel :

 $(function() { $(window).on('wheel', function(e) { var delta = e.originalEvent.deltaY; if (delta > 0) $('body').text('down'); else $('body').text('up'); return false; // this line is only added so the whole page won't scroll in the demo }); }); 
 body { font-size: 22px; text-align: center; color: white; background: grey; } 
  

Solución existente

Podría haber 3 soluciones de esta publicación y otro artículo de stackoverflow .

Solución 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; }); 

Solución 2

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

Solución 3

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

Prueba de navegador múltiple

No pude probarlo en Safari

Chrome 42 (Win 7)

  • Solución 1
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento
  • Soltion 2
    • Up: no funciona
    • Abajo: no funciona
  • Solución 3
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

Firefox 37 (Win 7)

  • Solución 1
    • Up: 20 eventos por 1 desplazamiento
    • Abajo: 20 eventos por 1 desplazamiento
  • Soltion 2
    • Up: no funciona
    • Abajo: 1 evento por 1 desplazamiento
  • Solución 3
    • Up: no funciona
    • Abajo: no funciona

IE 11 (Win 8)

  • Solución 1
    • Up: 10 eventos por 1 desplazamiento (efecto secundario: al final se produjo un desplazamiento hacia abajo)
    • Abajo: 10 eventos por 1 desplazamiento
  • Soltion 2
    • Up: no funciona
    • Abajo: no funciona
  • Solución 3
    • Up: no funciona
    • Abajo: 1 evento por 1 desplazamiento

IE 10 (Win 7)

  • Solución 1
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento
  • Soltion 2
    • Up: no funciona
    • Abajo: no funciona
  • Solución 3
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

IE 9 (Win 7)

  • Solución 1
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento
  • Soltion 2
    • Up: no funciona
    • Abajo: no funciona
  • Solución 3
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

IE 8 (Win 7)

  • Solución 1
    • Arriba: 2 eventos por 1 desplazamiento (efecto secundario: al final se produjo un desplazamiento hacia abajo)
    • Abajo: 2 ~ 4 eventos por 1 desplazamiento
  • Soltion 2
    • Up: no funciona
    • Abajo: no funciona
  • Solución 3
    • Up: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

Solución combinada

Comprobé que el efecto secundario de IE 11 e IE 8 provienen de la afirmación if else . Entonces, lo reemplacé con if else if statement como sigue.

A partir de la prueba de múltiples navegadores, decidí usar la Solución 3 para navegadores comunes y la Solución 1 para Firefox e IE 11.

Me referí a esta respuesta para detectar 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'); } }); } 
 $(function(){ var _top = $(window).scrollTop(); var _direction; $(window).scroll(function(){ var _cur_top = $(window).scrollTop(); if(_top < _cur_top) { _direction = 'down'; } else { _direction = 'up'; } _top = _cur_top; console.log(_direction); }); }); 

Demostración: http://jsfiddle.net/AlienWebguy/Bka6F/

Aquí hay una muestra que muestra una manera fácil de hacerlo. El script es:

 $(function() { var _t = $("#container").scrollTop(); $("#container").scroll(function() { var _n = $("#container").scrollTop(); if (_n > _t) { $("#target").text("Down"); } else { $("#target").text("Up"); } _t = _n; }); }); 

El #container es tu id div. El #target es solo para verlo funcionar. Cambie a lo que desea cuando sube o baja.

EDITAR

El OP no lo dijo antes, pero como usa un div con overflow: hidden , el desplazamiento no ocurre, entonces el script para detectar el scroll es lo menos posible. Bueno, ¿cómo detectar algo que no sucede?

Entonces, el OP mismo publicó el enlace con lo que quiere, entonces, ¿por qué no usar esa biblioteca? http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js .

La llamada es solo:

 $(function() { $(".scrollable").scrollable({ vertical: true, mousewheel: true }); }); 
 var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x $(document).bind(mousewheelevt, function(e) { var evt = window.event || e //equalize event object evt = evt.originalEvent ? evt.originalEvent : evt; //convert to originalEvent if possible var delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta //check for detail first, because it is used by Opera and FF if(delta > 0) { scrollup(); } else { scrolldown(); } } ); 

Puede usar este complemento simple para agregar scrollUp y scrollDown a su jQuery

https://github.com/phpust/JQueryScrollDetector

 var lastScrollTop = 0; var action = "stopped"; var timeout = 100; // Scroll end detector: $.fn.scrollEnd = function(callback, timeout) { $(this).scroll(function(){ // get current scroll top var st = $(this).scrollTop(); var $this = $(this); // fix for page loads if (lastScrollTop !=0 ) { // if it's scroll up if (st < lastScrollTop){ action = "scrollUp"; } // else if it's scroll down else if (st > lastScrollTop){ action = "scrollDown"; } } // set the current scroll as last scroll top lastScrollTop = st; // check if scrollTimeout is set then clear it if ($this.data('scrollTimeout')) { clearTimeout($this.data('scrollTimeout')); } // wait until timeout done to overwrite scrolls output $this.data('scrollTimeout', setTimeout(callback,timeout)); }); }; $(window).scrollEnd(function(){ if(action!="stopped"){ //call the event listener attached to obj. $(document).trigger(action); } }, timeout);