Иногда ленивая загрузка не работает в angular

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

    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. Однако в некоторых случаях ленивая загрузка не будет работать, и я не смог воспроизвести ошибку.

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

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

Изменить:

Дополнительная информация

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

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

например.

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

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

Изменить 2:

Вышеуказанное поведение также не детерминировано, но десятичная часть верна.

Ответы

Ответ 1

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

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

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

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

Ответ 2

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

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