Détection de la direction de défilement


120

J'essaye donc d'utiliser le JavaScript on scrollpour appeler une fonction. Mais je voulais savoir si je pouvais détecter la direction du défilement sans utiliser jQuery. Sinon, existe-t-il des solutions de contournement?

Je pensais simplement mettre un bouton «en haut», mais j'aimerais éviter cela si je le pouvais.

Je viens d'essayer d'utiliser ce code mais cela n'a pas fonctionné:

if document.body.scrollTop <= 0 {
    alert ("scrolling down")
} else {
    alert ("scrolling up")
}

C'est la wheelDeltade l'événement. Pas du tout multi-navigateur. Voir phrogz.net/js/wheeldelta.html
marekful

1
hmmm pas tout à fait ce que je cherchais mais j'apprécie votre aide: P D'autres suggestions?
dwinnbrown le

Réponses:


177

Il peut être détecté en stockant la scrollTopvaleur précédente et en comparant la valeur scrollTop actuelle avec elle.

JavaScript:

var lastScrollTop = 0;

// element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element.
element.addEventListener("scroll", function(){ // or window.addEventListener("scroll"....
   var st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
   if (st > lastScrollTop){
      // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
}, false);

20
Il serait plus sûr de s'initialiser lastScrollTopsur pageYOffset || scrollTop plutôt que de supposer 0
Ed Ballot

Entièrement d'accord !! Merci @EdBallot. Nous devrions initialiser la même chose sur l'événement window.onload.
Prateek le

@Prateek Merci pour votre réponse, mais cela ne fonctionne pas pour moi ... J'essaye de «changer de scène» dans ma webapp qui est construite avec Tumult Hype.
dwinnbrown le

J'ai ajouté quelques commentaires dans ma réponse, veuillez le vérifier. Je suppose que vous utilisez "element.addEventListener".
Prateek

@Prateek toujours rien j'ai peur. Cela pourrait-il être dû au fait que je l'exécute au chargement de la page? Voici une capture d'écran: i.imgur.com/Q0H0T4s.png
dwinnbrown

53

Un moyen simple de capturer tous les événements de défilement (tactile et molette)

window.onscroll = function(e) {
  // print "false" if direction is down and "true" if up
  console.log(this.oldScroll > this.scrollY);
  this.oldScroll = this.scrollY;
}

10
Bienvenue à SO, si vous ajoutez une description à votre réponse, cela peut être plus utile au PO et aux autres.
Alejandro Montilla

32

Utilisez ceci pour trouver la direction du défilement. C'est uniquement pour trouver la direction du défilement vertical. Prend en charge tous les navigateurs croisés.

var scrollableElement = document.body; //document.getElementById('scrollableElement');

scrollableElement.addEventListener('wheel', checkScrollDirection);

function checkScrollDirection(event) {
  if (checkScrollDirectionIsUp(event)) {
    console.log('UP');
  } else {
    console.log('Down');
  }
}

function checkScrollDirectionIsUp(event) {
  if (event.wheelDelta) {
    return event.wheelDelta > 0;
  }
  return event.deltaY < 0;
}

Exemple


2
C'est bien, mais ne semble fonctionner que pour l'utilisation de la molette de défilement
Jonathan.Brink

1
Depuis les webdocs MDN: Remarque: ne confondez pas l'événement wheel avec l'événement scroll. L'action par défaut d'un événement wheel est spécifique à l'implémentation et ne distribue pas nécessairement un événement scroll. Même lorsque c'est le cas, les valeurs delta * de l'événement wheel ne reflètent pas nécessairement la direction de défilement du contenu. Par conséquent, ne vous fiez pas aux propriétés delta * de l'événement wheel pour obtenir la direction du défilement. Au lieu de cela, détectez les changements de valeur de scrollLeft et scrollTop de la cible dans l'événement de défilement. developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
battaboombattabaam

10

Vous pouvez essayer de faire ceci.

function scrollDetect(){
  var lastScroll = 0;

  window.onscroll = function() {
      let currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // Get Current Scroll Value

      if (currentScroll > 0 && lastScroll <= currentScroll){
        lastScroll = currentScroll;
        document.getElementById("scrollLoc").innerHTML = "Scrolling DOWN";
      }else{
        lastScroll = currentScroll;
        document.getElementById("scrollLoc").innerHTML = "Scrolling UP";
      }
  };
}


scrollDetect();
html,body{
  height:100%;
  width:100%;
  margin:0;
  padding:0;
}

.cont{
  height:100%;
  width:100%;
}

.item{
  margin:0;
  padding:0;
  height:100%;
  width:100%;
  background: #ffad33;
}

.red{
  background: red;
}

p{
  position:fixed;
  font-size:25px;
  top:5%;
  left:5%;
}
<div class="cont">
  <div class="item"></div>
  <div class="item red"></div>
  <p id="scrollLoc">0</p>
</div>


cela ne fonctionne pas très bien pour moi. Quand je fais défiler jusqu'à une certaine hauteur, cela s'affiche vers le bas
Développeur

8

Ceci est un ajout à ce que prateek a répondu.Il semble y avoir un problème dans le code dans IE donc j'ai décidé de le modifier un peu rien d'extraordinaire (juste une autre condition)

$('document').ready(function() {
var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       console.log("down")
   }
   else if(st == lastScrollTop)
   {
     //do nothing 
     //In IE this is an important condition because there seems to be some instances where the last scrollTop is equal to the new one
   }
   else {
      console.log("up")
   }
   lastScrollTop = st;
});});

1
Merci pour votre indice ... cela semble être lié à l'option "Smooth Scrolling" d'IE
Kristo

5
  1. Initialiser une oldValue
  2. Obtenez la newValue en écoutant l'événement
  3. Soustrayez les deux
  4. Conclure du résultat
  5. Mettre à jour oldValue avec la newValue

// Initialisation

let oldValue = 0;

// Écoute de l'événement

window.addEventListener('scroll', function(e){

    // Get the new Value
    newValue = window.pageYOffset;

    //Subtract the two and conclude
    if(oldValue - newValue < 0){
        console.log("Up");
    } else if(oldValue - newValue > 0){
        console.log("Down");
    }

    // Update the old value
    oldValue = newValue;
});

3

Vous pouvez obtenir la position de la barre de défilement en utilisant document.documentElement.scrollTop. Et puis il s'agit simplement de le comparer à la position précédente.


Ok et pourrais-je toujours l'utiliser sur un site Web qui n'autorise pas traditionnellement le défilement (c'est-à-dire qu'il s'adapte à 100% de largeur et de hauteur au navigateur. Merci
dwinnbrown

2

Ce code simple fonctionnerait: Vérifiez la console pour les résultats.

let scroll_position = 0;
let scroll_direction;

window.addEventListener('scroll', function(e){
    scroll_direction = (document.body.getBoundingClientRect()).top > scroll_position ? 'up' : 'down';
    scroll_position = (document.body.getBoundingClientRect()).top;
    console.log(scroll_direction);
});

1

J'utilise personnellement ce code pour détecter la direction de défilement en javascript ... Il suffit de définir une variable pour stocker la valeur de lastscroll, puis de l'utiliser if & else

let lastscrollvalue;

function headeronscroll() {

    // document on which scroll event will occur
    var a = document.querySelector('.refcontainer'); 

    if (lastscrollvalue == undefined) {

        lastscrollvalue = a.scrollTop;

        // sets lastscrollvalue
    } else if (a.scrollTop > lastscrollvalue) {

        // downscroll rules will be here
        lastscrollvalue = a.scrollTop;

    } else if (a.scrollTop < lastscrollvalue) {

        // upscroll rules will be here
        lastscrollvalue = a.scrollTop;

    }
}

0

Code simple

// Events
$(document).on('mousewheel DOMMouseScroll', "element", function(e) {
    let delta = e.originalEvent.wheelDelta;
    
    if (delta > 0 || e.originalEvent.detail < 0) upScrollFunction();
    if (delta < 0 || e.originalEvent.detail > 0) donwScrollFunction();
}

Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la façon et / ou pourquoi il résout le problème améliorerait la valeur à long terme de la réponse.
Donald Duck
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.