Comment puis-je déterminer la direction d'un événement jQuery scroll?

je cherche quelque chose à cet effet:

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

des idées?

309
demandé sur ThinkingStiff 2010-12-01 19:57:58

22 réponses

non-fumeurs scrollTop vs précédent scrollTop

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st;
});
613
répondu Josiah Ruddell 2013-03-21 17:50:01

vous pouvez le faire sans avoir à garder la trace du parchemin précédent, comme tous les autres exemples l'exigent:

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

je ne suis pas un expert sur ce n'hésitez donc pas à approfondir les recherches, mais il semble que lorsque vous utilisez $(element).scroll , l'événement d'être écouté, pour un défilement de l'événement.

mais si vous écoutez spécifiquement un événement mousewheel en utilisant bind, l'attribut originalEvent du paramètre d'événement à votre callback contient des informations différentes. Une partie de cette information est wheelDelta . Si c'est positif, tu as remué la roue. Si c'est négatif, vous avez baissé le volant.

à mon avis, les événements mousewheel se déclenchent lorsque la roue de la souris tourne, même si la page ne défile pas; un cas dans lequel les événements "scroll" ne se déclenchent probablement pas. Si vous voulez, vous pouvez appeler event.preventDefault() au bas de votre rappel pour empêcher la page de défiler, et pour que vous puissiez utilisez l'événement mousewheel pour autre chose qu'un défilement de page, comme une fonctionnalité de zoom.

158
répondu cilphex 2012-05-11 09:15:37

stockez l'emplacement de défilement précédent, puis voyez si le nouveau est plus grand ou moins que cela.

voici un moyen d'éviter toute variable globale ( fiddle disponible ici ):

(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
27
répondu Skilldrick 2010-12-01 17:18:25

Solution

Il pourrait y avoir 3 solution à partir de ce message et de autre réponse .

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

Solution 2

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

Solution 3

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

Multi Browser Test

Je n'ai pas pu le tester sur Safari

chrome 42 (Win 7)

  • Solution 1
    • : 1 cas pour 1 scroll
    • vers le bas: 1 événement pour 1 rouleau
  • Soltion 2
    • : Pas de travail
    • vers le Bas : Pas de travail
  • Solution 3
    • : 1 cas pour 1 scroll
    • vers le bas: 1 événement pour 1 rouleau

Firefox 37 (Win 7)

  • Solution 1
    • : 20 événements par 1 scroll
    • vers le Bas : 20 événements par 1 scroll
  • Soltion 2
    • Up : Ne fonctionne pas
    • vers le bas: 1 événement pour 1 rouleau
  • Solution 3
    • : Pas de travail
    • vers le Bas : Pas de travail

IE 11 (Win 8)

  • Solution 1
    • : 10 événements par 1 rouleau (effet secondaire : défilement s'est produit à la dernière)
    • En bas: 10 événements pour 1 rouleau
  • Soltion 2
    • : Pas de travail
    • vers le Bas : Pas de travail
  • Solution 3
    • : Pas de travail
    • vers le bas: 1 événement pour 1 rouleau

IE 10 (Win 7)

  • Solution Un
    • : 1 cas pour 1 scroll
    • vers le bas: 1 événement pour 1 rouleau
  • Soltion 2
    • : Pas de travail
    • vers le Bas : Pas de travail
  • Solution 3
    • : 1 cas pour 1 scroll
    • vers le bas: 1 événement pour 1 rouleau

IE 9 (Win 7)

  • Solution 1
    • : 1 cas pour 1 scroll
    • vers le bas: 1 événement pour 1 rouleau
  • Soltion 2
    • : Pas de travail
    • vers le Bas : Pas de travail
  • Solution 3
    • Up : 1 événement pour 1 rouleau
    • vers le bas: 1 événement pour 1 rouleau

IE 8 (Win 7)

  • Solution 1
    • : 2 événements par 1 rouleau (effet secondaire : défilement s'est produit à la dernière)
    • vers le Bas : 2~4 événements par 1 scroll
  • Soltion 2
    • : Pas de travail
    • vers le Bas : Pas de travail
  • Solution 3
    • : 1 cas pour 1 scroll
    • vers le bas: 1 événement pour 1 rouleau

Solution Combinée

j'ai vérifié que les effets secondaires de IE 11 et IE 8 proviennent de l'énoncé if else . Donc, je l'ai remplacé par if else if déclaration suivant.

du test multi-navigateurs, j'ai décidé d'utiliser Solution 3 pour les navigateurs courants et Solution 1 pour firefox et IE 11.

j'ai appelé cette réponse pour détecter 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.);
    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');
            }
        });
    }
25
répondu Chemical Programmer 2017-05-23 10:31:38

je comprends qu'il y a déjà eu une réponse acceptée, mais j'ai voulu poster ce que j'utilise au cas où il pourrait aider n'importe qui. Je reçois la direction comme cliphex avec l'événement mousewheel mais avec le soutien pour Firefox. Il est utile de le faire de cette façon au cas où vous faites quelque chose comme verrouiller scroll et ne pouvez pas obtenir le haut de scroll actuel.

voir une version live ici .

$(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
    }
});
11
répondu souporserious 2015-01-28 20:15:44

Événement De Défilement

le scroll event se comporte étrangement en FF (il est tiré beaucoup de fois en raison de la douceur de défilement) mais il fonctionne.

Note: le scroll event actually est tiré en faisant glisser la barre de défilement, en utilisant les touches de curseur ou mousewheel.

//creates an element to print the scroll position
$("<p id='test'>").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 = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    $("#test").html(scrollText +
      "<br>innerHeight: " + self.innerHeight() +
      "<br>scrollHeight: " + scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>lastScrollTop: " + lastScrollTop);

    if (scrollHeight - scrollTop === self.innerHeight()) {
      console.log("► End of scroll");
    }

    //saves the current scrollTop
    self.data("lastScrollTop", scrollTop);
});

La Roue De L'Événement

vous pouvez également jeter un oeil à MDN, il expose une grande information sur le événement de roue .

Note: l'événement de la roue n'est déclenché qu'en utilisant le volant ; les touches du curseur et le déplacement de la barre de défilement ne déclenchent pas l'événement.

j'ai lu le document et l'exemple: écouter cet événement à travers le navigateur

et après quelques tests avec FF, IE, chrome, safari, j'ai fini avec ce snippet:

//creates an element to print the scroll position
$("<p id='test'>").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 = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    //console.log("Event: ", evt);
    $("#test").html(scrollText +
      "<br>clientHeight: " + this.clientHeight +
      "<br>scrollHeight: " + this.scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>deltaY: " + deltaY);
});
8
répondu jherax 2015-03-31 16:57:57

dans le cas où vous voulez juste savoir si vous faites défiler vers le haut ou vers le bas en utilisant un dispositif de pointeur (souris ou track pad), vous pouvez utiliser la propriété deltaY de l'événement wheel .

$('.container').on('wheel', function(event) {
  if (event.originalEvent.deltaY > 0) {
    $('.result').append('Scrolled down!<br>');
  } else {
    $('.result').append('Scrolled up!<br>');
  }
});
.container {
  height: 200px;
  width: 400px;
  margin: 20px;
  border: 1px solid black;
  overflow-y: auto;
}
.content {
  height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="content">
    Scroll me!
  </div>
</div>

<div class="result">
  <p>Action:</p>
</div>
6
répondu Yuri 2016-01-12 14:41:02
var tempScrollTop, currentScrollTop = 0; 

$(window).scroll(function(){ 

   currentScrollTop = $("#div").scrollTop(); 

   if (tempScrollTop > currentScrollTop ) {
       // upscroll code
   }
  else if (tempScrollTop < currentScrollTop ){
      // downscroll code
  }

  tempScrollTop = currentScrollTop; 
} 

ou utilisez la extension de la mouse , voir ici .

3
répondu Adam 2010-12-01 17:06:42

pour ignorer tout snap / momentum / rebondir en haut et en bas de la page, voici une version modifiée de réponse acceptée 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;
});
3
répondu Andrew Tibbetts 2017-05-23 12:18:32

vous pouvez déterminer la direction de 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');
    }
});
3
répondu J. Kovacevic 2016-12-31 11:07:13

j'ai vu beaucoup de versions de bonnes réponses ici, mais il semble que certaines personnes ont des problèmes de navigateur croisé donc ceci est ma solution.

Je l'ai utilisé avec succès pour détecter la direction en FF, IE et Chrome ... Je ne l'ai pas testé en safari car j'utilise windows en général.

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

gardez à l'esprit que je l'utilise aussi pour arrêter tout défilement donc si vous voulez que le défilement se produit encore, vous devez supprimer le e.preventDefault(); e.stopPropagation();

2
répondu GoreDefex 2014-11-13 13:10:25

utilisez ceci pour trouver la direction du rouleau. Ceci est seulement pour trouver la direction du rouleau Vertical. Prend en charge tous les navigateurs.

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

    }

exemple

2
répondu Vasi 2017-06-15 16:08:39

stock un incrément dans le .data () de l'élément laminé, vous serez alors en mesure de tester le nombre de fois que le rouleau atteint en haut.

1
répondu Spacefrog 2013-12-11 16:32:53

Keep it simple:

jQuery Écouteur d'Événement:

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

Vanille JavaScript Écouteur D'Événement:

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

La Fonction Reste La Même:

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

j'ai écrit un post plus approfondi sur elle ici ​​​​​​​

1
répondu CR Rollyson 2016-12-29 22:05:54

vous pouvez utiliser les deux options scroll et mousewheel pour suivre les mouvements à la fois.

 $('body').bind('scroll mousewheel', function(event) {

if (event.originalEvent.wheelDelta >= 0) {
      console.log('moving down');   
    }
    else {
      console.log('moving up'); 
    }
});

vous pouvez aussi remplacer "body" par (window).

1
répondu Zeeshan Rasool 2017-03-11 23:13:59

ce code fonctionne très bien avec IE, Firefox, Opera et Chrome:

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

'roue de la roulette de la souris' et la propriété deltaY doit être utilisé en bind() de la fonction.

rappelez-vous : vous êtes l'utilisateur doit mettre à jour leur système et les navigateurs pour des raisons de sécurité. En 2018, Les excuses de "j'ai IE 7" est un non-sens. Nous devons éduquer les utilisateurs.

bonne journée :)

1
répondu Cyril Morales 2018-10-02 13:54:55

pour ceux qui ont des problèmes avec le défilement élastique, s'il vous plaît utiliser cette réponse

comment détecter la direction de défilement

0
répondu Timothy Dalton 2017-05-23 12:18:32

dans le .data() de l'élément vous pouvez stocker un JSON et des valeurs de test pour lancer des événements

{ top : 1,
   first_top_event: function(){ ...},
   second_top_event: function(){ ...},
   third_top_event: function(){ ...},
   scroll_down_event1: function(){ ...},
   scroll_down_event2: function(){ ...}
}
0
répondu Spacefrog 2013-12-30 08:47:53

c'est une détection simple et facile pour quand l'utilisateur s'éloigne du haut de la page et pour quand ils reviennent au haut.

$(window).scroll(function() {
    if($(window).scrollTop() > 0) {
        // User has scrolled
    } else {
        // User at top of page
    }
});
0
répondu Kbam7 2015-08-04 19:33:01

il s'agit d'une solution optimale pour détecter la direction juste lorsque l'Utilisateur termine le défilement.

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

});
0
répondu Mahmoud 2015-10-21 16:24:01

, Vous Devriez essayer ce

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();
    });
0
répondu thakurdev 2017-08-01 11:21:16

Pourquoi personne ne l' event objet retourné par jQuery , faites défiler ?

$window.on('scroll', function (event) {
    console.group('Scroll');
    console.info('Scroll event:', event);
    console.info('Position:', this.pageYOffset);
    console.info('Direction:', event.originalEvent.dir); // Here is the direction
    console.groupEnd();
});

j'utilise chromium et je n'ai pas vérifié sur les autres navigateurs s'ils ont la propriété dir .

0
répondu Jiab77 2018-09-26 00:44:15