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? Ellos parecen ser capaces de hacerlo. Desafortunadamente el código fuente está comprimido, así que no hay suerte...

¡Gracias!!

Author: isherwood, 2011-08-23

8 answers

Me las arreglé para averiguarlo 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;
 });
 101
Author: Rik de Vos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-17 00:11:15

El siguiente ejemplo escuchará solo el desplazamiento del RATÓN, sin movimientos táctiles ni de trackpad.

Utiliza jQuery.on () (A partir de jQuery 1.7, el .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/

 46
Author: honk31,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-05 13:11:48

Este merece una actualización-hoy en día tenemos el wheel evento:

$(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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

El soporte ha sido bastante bueno en los navegadores modernos desde hace bastante tiempo:

  • Cromo 31+
  • Firefox 17+
  • IE9 +
  • Opera 18 +
  • Safari 7 +

Https://developer.mozilla.org/en-US/docs/Web/Events/wheel

Si se requiere un soporte más profundo del navegador, probablemente sea mejor usar mousewheel.js lugar de jugar sobre :

Https://plugins.jquery.com/mousewheel /

$(function() {

$(window).mousewheel(function(turn, delta) {

	if (delta > 0) $('body').text('up');
	else $('body').text('down');

	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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
 36
Author: Shikkediel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-26 07:45:29

Solución existente

Podría haber 3 solución 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 Multi Navegador

No pude probarlo en Safari

Chrome 42 (Win 7)

  • Solución 1
    • Subir: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 scroll
  • Solción 2
    • Subir: No funciona
    • Abajo : No funciona
  • Solución 3
    • Subir: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

Firefox 37 (Win 7)

  • Solución 1
    • Subir: 20 eventos por 1 scroll
    • Abajo: 20 eventos por 1 scroll
  • Solción 2
    • Subir: No funciona
    • Abajo: 1 evento por 1 scroll
  • Solución 3
    • Subir: No funciona
    • Abajo : No funciona

IE 11 (Win 8)

  • Solución 1
    • Arriba : 10 eventos por 1 desplazamiento (efecto secundario: desplazamiento hacia abajo ocurrió por fin)
    • Abajo: 10 eventos por 1 scroll
  • Solción 2
    • Subir: No funciona
    • Abajo : No funciona
  • Solución 3
    • Subir: No funciona
    • Abajo: 1 evento por 1 scroll

IE 10 (Win 7)

  • Solución 1
    • Subir: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento
  • Solción 2
    • Subir: No funciona
    • Abajo : No funciona
  • Solución 3
    • Subir: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

IE 9 (Win 7)

  • Solución 1
    • Subir: 1 evento por 1 scroll
    • Abajo: 1 evento por 1 desplazamiento
  • Solción 2
    • Subir: No funciona
    • Abajo : No funciona
  • Solución 3
    • Subir: 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: desplazamiento hacia abajo ocurrió por fin)
    • Abajo: 2~4 eventos por 1 scroll
  • Solción 2
    • Subir: No funciona
    • Abajo : No funciona
  • Solución 3
    • Subir: 1 evento por 1 desplazamiento
    • Abajo: 1 evento por 1 desplazamiento

Solución combinada

He comprobado que el efecto secundario de IE 11 e IE 8 viene de la declaración if else. Por lo tanto, lo reemplazé con la declaración if else if como sigue.

De la prueba multi navegador, decidí usar Solución 3 para navegadores comunes y Solución 1 para firefox e IE 11.

Me referí 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');
            }
        });
    }
 22
Author: Chemical Programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:33
$(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);
    });
});

Demo: http://jsfiddle.net/AlienWebguy/Bka6F /

 9
Author: AlienWebguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-23 00:22:02

Aquí hay un ejemplo 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 div id. El #target es solo para verlo funcionar. Cambia a lo que quieras cuando estés arriba o abajo.

EDITAR

El OP no lo dijo antes, pero como está usando un div con overflow: hidden, el desplazamiento no ocurre, entonces el script para detectar el desplazamiento es el menor de ellos. Bueno, ¿cómo detectar algo que no sucede?!

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

La llamada es simplemente:

$(function() {
    $(".scrollable").scrollable({ vertical: true, mousewheel: true });
});
 0
Author: Erick Petrucelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-23 00:46:49
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();
            }   
    }
);
 0
Author: Jithin U. Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-24 08:27:55

Puede usar este simple plugin 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);
 0
Author: user122293,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 16:04:11