2016-07-28 8 views
14

Я встречаю странное поведение для следующего кода.Lazy loading иногда не работает в угловом

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

выше кусок кода, который обнаруживает, если в нижней части страницы будет достигнута, если ее достигнуто это будет вызывать любые функции связываются с myDirective

Основной проблемой является то, что большую часть времени ленивые погрузочные работы, и myDirective получает успешное название. Однако в некоторых случаях ленивая загрузка не будет работать, и я не смог воспроизвести ошибку.

Я пробовал использовать различные размеры экрана, разные браузеры, но похоже, что ошибка происходит случайно.

Возможно, кому-то это случилось с ними раньше, и может указать мне направление?

Edit:

Больше информации

Я был в состоянии воспроизвести ошибку после того, как немного поэкспериментировать.

В основном, когда увеличение в процентах от браузера < 100 %, window.pageY возвращает десятичное значение, которое немного неточным, которые вызывают windowBottom быть выключен с помощью 0.1 к 0.9

например.

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

Кто-нибудь знает, почему это происходит?

Edit 2:

Такое поведение также не детерминированной, а дробная часть верно. !

+1

Это довольно необычный способ разработки угловой директивы; это противоречит принципам разработки углов, чтобы начать связывать выполнение JavaScript с конкретными событиями пользовательского интерфейса. – Claies

+0

У вас нет консоли Chrome в нижней части экрана? Мне кажется, что это может немного причудливо повлиять на восприятие высоты подобного кода. – cYrixmorten

+0

@cYrixmorten У меня не было консоли Chrome chrome в нижней части экрана, хотя я и пробовал это, но поведение по-прежнему не детерминировано. – testing

ответ

3

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

Это одна странность не только в JavaScript; это фактически превалирующая проблема в информатике, и она затрагивает многие языки. Выходной сигнал составляет 0,0000000000000004.

Это связано с проблемой, называемой машинной точностью. Когда JavaScript пытается выполнить строку выше, она преобразует значения в их двоичные эквиваленты. Здесь начинается проблема. 0,1 не является действительно 0,1, а скорее его двоичным эквивалентом, который является почти-новым (но не идентичным) значением. По сути, как только вы пишете значения, они обречены на то, чтобы потерять свою точность. Возможно, вам просто нужны два простых десятичных знака, но то, что вы получаете, как отмечает Крис Пайн, - это двоичная арифметика с плавающей запятой. Похоже на то, что ваш текст переведен на русский язык, но он становится белорусским. Похоже, но не то же самое.

Подробнее ... here. Не копаясь в источнике браузера, я бы предположил, что ваша проблема проистекает из этого.

+0

Сокращенный. Не отвечает на вопрос ОП или решает проблему. – DhruvPathak

+0

Досрочное голосование. Он отвечает на вопрос. Если вы прочитаете дополнение к вопросу, выясняется, что проблема связана с тем, как JavaScript обрабатывает математические операции. –

+0

@DhruvPathak «Кто-нибудь знает, почему это происходит?» в конечном счете, вопрос OP, поскольку он уже обнаружил виновника самостоятельно – adamdport

3

Учитывая проблемы точности с плавающей точкой, вы можете захотеть ослабить условие, чтобы вместо этого проверить, если два значения меньше 1 пикселя.Например:

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

Отлично! это помогло мне mcgraphix :) –