【问题标题】:Lazy loading occasionally doesn't work in angular延迟加载有时在角度不起作用
【发布时间】:2016-07-28 17:58:25
【问题描述】:

我在下面的代码中遇到了一些奇怪的行为。

    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 返回一个稍微不准确的十进制值,这会导致 windowBottom0.1 关闭到 0.9

例如。

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

有人知道为什么会这样吗?

编辑 2:

上述行为也是非确定性的,但小数部分为真。

【问题讨论】:

  • 这是设计角度指令的一种相当不寻常的方式;开始将 JavaScript 的执行与特定的 UI 事件联系起来,这与 Angular 的设计原则背道而驰。
  • 你没有碰巧在屏幕底部有 chrome dev 控制台吗?在我看来,它可能会对类似代码的高度感知产生一些奇怪的影响。
  • @cYrixmorten 我在屏幕底部没有 chrome 开发控制台,虽然我确实尝试过,但行为仍然不确定。
  • 虽然这不一定是修复,但它可能仍然是修复......因为它偏离了 0.1 到 0.9,你不能使用地板或天花板吗?
  • @ChrisStanley 这正是我所做的,但我想知道原因。

标签: javascript angularjs infinite-scroll


【解决方案1】:

0.1 + 0.2 !== 0.3

这不仅在 JavaScript 中很奇怪;它实际上是计算机科学中的一个普遍问题,它影响了许多语言。其输出为 0.30000000000000004。

这与称为机器精度的问题有关。当 JavaScript 尝试执行上面的行时,它会将值转换为它们的二进制等价物。 这就是问题开始的地方。 0.1 并不是真正的 0.1,而是它的二进制等价物,这是一个接近(但不相同)的值。本质上,一旦你写出这些值,它们就注定会失去精确性。您可能只想要两个简单的小数,但正如 Chris Pine 所指出的,您得到的是二进制浮点运算。有点像希望您的文本翻译成俄语但得到白俄罗斯语。相似,但不一样。

您可以阅读更多here。如果不深入研究浏览器源代码,我猜你的问题源于此。

【讨论】:

  • 投反对票。不回答 OP 的问题或解决问题。
  • 赞成。它确实回答了这个问题。如果您阅读问题的补充内容,就会发现问题在于 JavaScript 如何处理数学运算。
  • @DhruvPathak “有人知道为什么会这样吗?”最终是 OP 的问题,因为他已经自己发现了罪魁祸首
【解决方案2】:

考虑到浮点精度问题,您可能需要放宽条件以检查两个值是否相差小于 1 个像素。例如:

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

【讨论】:

  • 太棒了!这对我有帮助 mcgraphix :)
猜你喜欢
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
相关资源
最近更新 更多