2013-03-07 5 views
12

Ich muss die Richtung erkennen, in der ein Benutzer scrollt - "nach oben" oder "nach unten". Basierend auf dem Code in dieser Antwort gefunden: How can I determine the direction of a jQuery scroll event?jQuery/JavaScript: Scroll-Richtung erkennen - Code Struktur Problem

Ich habe versucht, es in eine Funktion zu wickeln, so dass es ein bisschen differenzierter ist - aber leider funktioniert es nicht. Ich denke, es hat etwas damit zu tun, wie ich den Wert zurückgebe, aber die Richtung ist immer "oben". Da JavaScript ziemlich neu ist, habe ich Probleme, dieses Problem zu lösen. Hier

ist der Code:

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

    }); 

}); 

Und ich habe auch eine Fiddle einrichten.

Könnten Sie mir bitte helfen herauszufinden, wo das Problem liegt?

+0

Ich würde empfehlen, Ihre Funktions- und Variablendeklarationen außerhalb der Ready-Funktion zu verschieben. Ich bin mir nicht sicher, ob das das Problem lösen wird, aber es könnte einen Versuch wert sein. –

+0

@AdamPlocher Danke für den Tipp, aber es hat nicht geholfen. Gibt es einen generellen Vorteil, dies zu tun? Vielleicht leistungsorientiert? – Sven

Antwort

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

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

}); 

Sie forderten detectDirection() zweimal während jedes Scroll-Ereignis. Der erste hat die richtige Richtung erkannt, aber der zweite hat ihn am selben Ort gesehen, also ist er "nach oben" zurückgekehrt, und das hast du protokolliert.

+2

Ah natürlich, ich sehe! Vielen Dank! – Sven

2

Sehen Sie, was Sie mit diesem erhalten:

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

Zusätzlich zu dem, was Barmar angegeben, könnten Sie von der Linie loszuwerden (der Anruf) über der Konsole ausgegeben und nur halten:

console.log(detectDirection()); 
+1

Ja, Sie haben völlig Recht.Ich habe gerade nicht bemerkt, dass 'console.log (detectDirection());' auch tatsächlich * die Funktion aufruft, obwohl es eigentlich ziemlich klar ist. – Sven

+1

Wenn das dein einziger JS-Fehler ist, wird es dir gut gehen;) – vol7ron

2

der Code, wie es wird nicht funktionieren, da wir nie die lastScrollTop aktualisieren, hier ist der Arbeits Code ...

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

Ich habe 0 als statisch/1 als Bildlauf/-1 als Bildlauf verwendet

Hoffe, dass jemand hilft.

0

Ich gebe eine neue Antwort, denn während die Antwort von BarMar Ihr unmittelbares Problem löst, hilft Ihnen die Lösung nicht, den Code so zu strukturieren, dass Sie zwei Dinge tun können.

  1. Scrollen Sie das Scroll-Objekt breiter aus, damit Sie anderswo auf seine Attribute zugreifen können. Dies würde Ihnen erlauben, etwas zu tun, wenn die Bildlaufposition einen bestimmten Wert hat.

  2. Verbessern Sie die Leistung des Scrollens.

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

Anstatt mit .bind(), sollten Sie verwenden .on(), gemäß dem jQuery .bind() documentation.

Die Immediately Invoked Function Expression (IIFE) zur Verbesserung der Scroll-Leistung kommt von der MDN documentation for the scroll event.