2013-03-07 8 views
12

Muszę wykryć kierunek w którym użytkownik przewija - "w górę" lub "w dół". Na podstawie kodu znalezionego w tej odpowiedzi: How can I determine the direction of a jQuery scroll event?jQuery/JavaScript: Wykrywanie kierunku przewijania - kwestia struktury kodu

Próbowałem zawinąć go w funkcję, więc jest nieco bardziej zróżnicowany - ale niestety, nie działa. Myślę, że ma to coś wspólnego z tym, jak zwracam wartość, ale kierunek jest zawsze "w górę". Będąc całkiem nowym w JavaScript mam problemy z rozwiązaniem tego problemu.

Oto kod:

$(document).ready(function() { 

    'use strict'; 

    var lastScrollTop = 0, 
     st, 
     direction; 

    function detectDirection() { 

     st = window.pageYOffset; 

     if (st > lastScrollTop) { 
      direction = "down"; 
     } else { 
      direction = "up"; 
     } 

     lastScrollTop = st; 

     return direction; 

    } 

    $(window).bind('scroll', function() { 

     detectDirection(); 
     console.log(detectDirection()); 

    }); 

}); 

A ja również skonfigurować Fiddle.

Czy mógłbyś mi pomóc dostrzec gdzie jest problem?

+0

Zalecam przeniesienie funkcji i deklaracji zmiennych poza gotową funkcję. Nie jestem pewien, czy to rozwiąże problem, ale może warto spróbować. –

+0

@AdamPlocher Dzięki za wskazówkę, ale to nie pomogło. Czy jest jednak jakaś ogólna korzyść z tego? Może wydajność jest mądra? – Sven

Odpowiedz

6
$(window).bind('scroll', function() { 

    var dir = detectDirection(); 
    console.log(dir); 

}); 

Dwa razy dzwoniłeś pod numer detectDirection() podczas każdego zdarzenia przewijania. Pierwszy z nich wykrył prawidłowy kierunek, ale drugi po prostu zobaczył go w tym samym miejscu, więc powrócił "do góry" i to się właśnie zalogowało.

+2

Ach, oczywiście, widzę! Dziękuję Ci! – Sven

2

Zobacz co się z tym:

if (st > lastScrollTop) { 
    direction = "down"; 
} else if (st < lastScrollTop){ 
    direction = "up"; 
} else { 
    direction = "static"; 
} 

Oprócz tego, co Barmar stwierdził, można pozbyć się linii (połączenia) powyżej wyjścia konsoli i po prostu:

console.log(detectDirection()); 
+1

Tak, masz całkowitą rację.Po prostu nie zdawałem sobie sprawy, że 'console.log (detectDirection());' również faktycznie * wywołuje * funkcję, chociaż jest całkiem jasne. – Sven

+1

Jeśli to twój jedyny błąd w JS, wszystko będzie dobrze;) – vol7ron

2

Kod jak to nie zadziała, ponieważ nigdy nie aktualizuje lastScrollTop, tutaj jest kod roboczych ...

$(function(config){ 
    var lastScrollTop = 0, // setting initial scrolltop as top of page 
     direction; // direction of scroll 1)up -1)down 0)static 

    function detectDirection() { 
     // current scrollTop can't be cached or in the local global scope 
     var st = window.pageYOffset; 

     if (st > lastScrollTop) { 
      // scrolling down 
      direction = -1; 
     } else if (st < lastScrollTop){ 
      // scrolling up 
      direction = 1; 
     } else { 
      // static 
      direction = 0; 
     } 

     // updated lastscrolltop with new current top 
     lastScrollTop = st; 

     // return the direction 
     return direction; 
    }` 

Użyłem 0 jako statyczny/1 jako przewijanie w górę/-1 jako przewijanie w dół

Mam nadzieję, że komuś pomóż.

0

Dostarczam nowej odpowiedzi, ponieważ podczas gdy odpowiedź BarMar rozwiązuje twój natychmiastowy problem, rozwiązanie nie pomaga w skonstruowaniu kodu w sposób, który pozwoli ci zrobić dwie rzeczy.

  1. Szerzej zakres przedmiotu przewijania, umożliwia dostęp do jego atrybutów w innym miejscu. Umożliwiłoby to zrobienie czegoś, jeśli pozycja przewijania jest określoną wartością.

  2. Poprawić wydajność przewijania.

    // Your current functionality 
    $(document).ready(function() { 
        var scroll = { 
        down: true, 
        pos: 0 
        }; 
        var scrollPos; 
    
        var detectDirection = function() { 
        scrollPos = window.pageYOffset; 
    
        if (scrollPos > scroll.pos) { 
         scroll.down = true; 
        } else { 
         scroll.down = false; 
        } 
    
        scroll.pos = scrollPos; 
        }; 
    
        $(window).on('optimizedScroll', function() { 
        detectDirection(); 
    
        // Do something based on scroll direction 
        if (scroll.down == true) { 
         // fooFunction(); 
        } else { 
         // barFunction(); 
        } 
    
        // Do something based on scroll position, 
        // where scrollTrigger is a number 
        if (scroll.pos > scrollTrigger) { 
         // bazFunction(); 
        } 
        }); 
    }); 
    
    // Improve scroll performance 
    (function() { 
        var throttle = function(type, name, obj) { 
         var obj = obj || window; 
         var running = false; 
         var func = function() { 
         if (running) { 
          return; 
         } 
         running = true; 
         requestAnimationFrame(function() { 
         obj.dispatchEvent(new CustomEvent(name)); 
          running = false; 
         }); 
         }; 
         obj.addEventListener(type, func); 
        }; 
    
        throttle('scroll', 'optimizedScroll'); 
    })(); 
    

Zamiast używać .bind(), należy użyć .on(), jak na jQuery .bind() documentation.

The Immediately Invoked Function Expression (IIFE) dla poprawy wydajności przewijania pochodzi z MDN documentation for the scroll event.

Powiązane problemy