我遇到以下代码的一些奇怪行为。
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
成功调用。但有些时候延迟加载不起作用,我无法重现错误。
我尝试了不同的屏幕大小,不同的浏览器,但似乎这个bug只是随机发生的。
也许之前有人发生过这种情况,可以指出方向吗?
编辑:
更多信息
经过一些实验后,我能够重现这个错误。
基本上,当浏览器的放大百分比为< 100 %
时,window.pageY
会返回一个稍微不准确的小数值,导致windowBottom
被0.1
关闭到0.9
例如
console.log(windowBottom); // 1646.7747712336175
console.log(docHeight); // 1647
有谁知道为什么会这样?
编辑2:
上述行为也是非确定性的,但小数部分为真。
答案 0 :(得分:3)
0.1 + 0.2!== 0.3
这不仅仅是JavaScript中的奇怪之处;它实际上是计算机科学中的一个普遍问题,它影响着许多语言。这个输出是0.30000000000000004。
这与称为机器精度的问题有关。当JavaScript尝试执行上面的行时,它会将值转换为它们的二进制等价物。 这是问题开始的地方。 0.1实际上不是0.1,而是它的二进制等价,它是近似(但不相同)的值。从本质上讲,只要你写出这些价值观,它们就注定要失去精确度。你可能只想要两个简单的小数,但正如Chris Pine所说,你得到的是二进制浮点运算。有点像想要你的文字翻译成俄语但获得白俄罗斯语。相似,但不一样。
您可以阅读更多here。如果不深入研究浏览器资源,我猜你的问题源于此。
答案 1 :(得分:3)
考虑到浮点精度问题,您可能希望放松条件以检查两个值是否小于1个像素不同。例如:
if (Math.abs(windowBottom - docHeight) < 1) {
scope.$apply(attribute.myDirective);
}