【发布时间】:2018-07-05 19:43:12
【问题描述】:
我遇到了一个问题,有时当我在网页中的 JavaScript 获得 window.pageYOffset 的值时,即使我知道用户正在查看文档的中间并且它的值应该很大,但它却莫名其妙地为 0,例如650000。请注意,很大一部分时间我得到了一个合理的值。但有时它是零,有时它是一个看似随机的小值,比如在 6000 范围内,而我期望 650000。
与其发布一堆代码,我想问一些一般性问题来帮助我弄清楚从哪里开始寻找。
此页面显示在 iOS WKWebView 中(尽管此问题可以在 Android 应用程序的类似上下文中表现出来)。我的应用程序中的 JavaScript 方法可以通过以下几种方式之一调用:
当我的应用被通知页面已完成加载(通过委托方法)时,它会使用 Objective-C 代码中的
evaluateJavaScript调用 JavaScript 方法。我的应用程序可以在其他时间调用
evaluateJavaScript,而不仅仅是在页面完成加载时。可能会调用 JavaScript 函数作为计时器触发的结果。
滚动事件可能会调用 JavaScript 函数。
我一直在假设页面上的 JavaScript 代码始终在单个线程中运行。也就是说,我没有遇到计时器触发、滚动事件发生,甚至是来自 Objective-C 代码(使用 evaluateJavaScript)的调用都会中断 JavaScript 运行时中可能发生的任何事情的情况。因此,当我尝试访问它时,我不必担心会中断一些正在修改window.pageYOffset 的系统级活动。
所以这是我的第一个问题:我的代码之外的某个人在单个线程上调用我的 JavaScript 方法,而不是在另一个线程上与 DOM 胡闹,我是否正确?
我的第二个问题是相关的:我的代码修改了 DOM,添加和删除了 div 元素。我一直假设这些修改是同步的——如果我插入一个带有insertAfter 或insertBefore 的元素,我希望子/父/兄弟指针在返回时是准确的,并且我假设我可以立即访问事物就像其他元素上的 top 和 left 值一样,它们将被更新以反映插入/删除的元素。关键是我不应该在进行更改之后和检查window.pageYOffset 之类的内容之前“等待”DOM“稳定”。这是正确的吗?
另一个线索:为了帮助缓解这种情况,我很幸运,只需在函数顶部测试 window.pageYOffset 是否为零。如果它为零,我会在计时器上调用自己(仅延迟 1 毫秒)。如果我这样做的时间足够长,它最终将是非零的。
也许在阅读完所有这些之后,没有任何细节是相关的,并且您知道基本问题的答案:为什么我有时会在 window.pageYOffset 中得到一个无效值(通常为 0),而同一行代码给出了一个有效值其他时间的价值。
【问题讨论】:
-
与其信守诺言,不如发布一些代码?
-
问题是这里的 JavaScript 大约有 4000 行。我的一般问题实际上并不需要任何代码——来自我的 iOS 应用程序的 JavaScript 调用、来自计时器触发的 JavaScript 调用、来自事件处理程序的 JavaScript 调用以及所有正在运行的系统级 DOM 代码在一个线程上?其次,在插入或删除一个元素后,是否可以预期
window.pageYOffset和任何其他大小/位置值已更新以反映更改?
标签: javascript ios wkwebview