2016-07-28 20 views
14

Ich bin etwas seltsames Verhalten für den folgenden Code.Lazy Laden funktioniert gelegentlich nicht in eckigen

function linkFunc(scope, element, attribute) { 
     var page = angular.element($window); 

     page.bind('scroll', function() { 

      var windowHeight = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight; 
      var body = document.body, html = document.documentElement; 
      var docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); 
      var windowBottom = windowHeight + window.pageYOffset; 

      if (windowBottom >= docHeight) { 
       scope.$apply(attribute.myDirective); 
      } 
     }); 
    } 

Die oben ist ein Stück Code, wenn der Boden der Seite erfasst wird erreicht, wenn ihr es, was Funktion bind erreicht rufen myDirective

Das Hauptproblem, dass die meiste Zeit ist die Lazy Loading funktioniert, und myDirective wird erfolgreich aufgerufen. Manchmal funktioniert das Lazy Loading jedoch nicht und ich konnte den Fehler nicht reproduzieren.

Ich probierte verschiedene Bildschirmgröße, andere Browser, aber es scheint, als ob der Fehler zufällig passiert.

Vielleicht ist jemand ihnen das schon einmal passiert, und kann mir eine Richtung zeigen?

Edit:

Weitere Informationen

Ich war in der Lage, den Fehler nach einem bisschen experimentieren zu reproduzieren.

Grundsätzlich, wenn der Zoom in Prozent des Browser < 100 % ist, window.pageY liefert einen Dezimalwert, der geringfügig ungenau ist, welche windowBottom verursachen off 0.1 zu 0.9

beispielsweise durch eine sein.

  console.log(windowBottom); // 1646.7747712336175 
      console.log(docHeight); // 1647 

Weiß jemand, warum das passiert?

Edit 2:

Das obige Verhalten auch nicht deterministisch ist, aber der Dezimalteil ist wahr. !

+1

Dies ist eine eher ungewöhnliche Art, eine Winkelanweisung zu entwerfen; Es widerspricht den Designprinzipien von angular, um die Ausführung von JavaScript an bestimmte Benutzeroberflächenereignisse zu binden. – Claies

+0

Sie haben nicht zufällig die Chrome-dev-Konsole am unteren Bildschirmrand? Scheint mir, dass es ein bisschen skurrilen Einfluss auf die Höhenwahrnehmung von ähnlichem Code haben kann. – cYrixmorten

+0

@cYrixmorten Ich hatte keine Chrome-dev-Konsole am unteren Bildschirmrand, obwohl ich das versucht habe, aber das Verhalten ist immer noch nicht deterministisch. – testing

Antwort

3

0,1 + 0,2 == 0,3

Dies ist eine Kuriosität nicht nur in JavaScript; Es ist tatsächlich ein vorherrschendes Problem in der Informatik, und es betrifft viele Sprachen. Die Ausgabe davon ist 0.30000000000000004.

Dies hat mit einem Problem zu tun, das als Maschinengenauigkeit bezeichnet wird. Wenn JavaScript versucht, die obige Zeile auszuführen, werden die Werte in ihre binären Entsprechungen konvertiert. Hier beginnt das Problem. 0.1 ist nicht wirklich 0.1, sondern sein binäres Äquivalent, welches ein fast isch (aber nicht identischer) Wert ist. Im Wesentlichen, sobald Sie die Werte schreiben, sind sie dazu verdammt, ihre Präzision zu verlieren. Vielleicht wollten Sie nur zwei einfache Dezimalzahlen, aber Sie erhalten, wie Chris Pine feststellt, binäre Gleitkommaarithmetik. So, als ob Sie Ihren Text ins Russische übersetzen, aber Weißrussisch bekommen möchten. Ähnlich, aber nicht gleich.

Sie können mehr lesen here. Ohne in die Browser-Quelle zu gehen, würde ich vermuten, dass Ihr Problem davon herrührt.

+0

Downvoted. Beantwortet nicht die Frage des OP oder löst das Problem. – DhruvPathak

+0

Up abstimmen. Es beantwortet die Frage. Wenn Sie den Zusatz zu der Frage lesen, stellt sich heraus, dass das Problem darin liegt, wie JavaScript mit mathematischen Operationen umgeht. –

+0

@DhruvPathak "Weiß jemand, warum das passiert?" ist letztlich die Frage von OP, wie er bereits den Schuldigen selbst entdeckt hat – adamdport

3

Angesichts der Gleitkomma-Genauigkeitsprobleme möchten Sie möglicherweise Ihre Bedingung zu überprüfen, stattdessen überprüfen, ob die beiden Werte weniger als 1 Pixel unterschiedlich sind.Zum Beispiel:

if (Math.abs(windowBottom - docHeight) < 1) { 
    scope.$apply(attribute.myDirective); 
} 
+0

Großartig! das hat mir mcgraphix geholfen :) –