【问题标题】:Determining when stringByEvaluatingJavaScriptFromString has finished确定 stringByEvaluatingJavaScriptFromString 何时完成
【发布时间】:2011-01-14 07:07:16
【问题描述】:

我有一个UIWebView,它会加载一个 HTML 页面。这个页面上有两个按钮,比如退出和提交。我不希望用户能够单击退出按钮,因此一旦页面完成加载(即调用webViewDidFinishLoad),我使用stringByEvaluatingJavaScriptFromString 通过操作HTML 删除这些按钮之一。我还在webViewDidStartLoad 上禁用了UIWebView 上的用户交互,并在webViewDidFinishLoad 上再次启用它。

我发现的问题是stringByEvaluatingJavaScriptFromString 需要一两秒钟才能完成,而且似乎是在它自己的线程中完成的。所以发生的事情是调用了webViewDidFinishLoad,在UIWebView 上启用了用户交互,如果用户很快,他们可以在stringByEvaluatingJavaScriptFromString 完成之前单击退出按钮。由于stringByEvaluatingJavaScriptFromString 似乎在它自己的线程上,无法知道它何时完成(它不调用webViewDidFinishLoad),所以完全阻止用户点击我可以看到的退出按钮的唯一方法是只启用用户交互延迟一段时间后在 UIWebView 上,这是不可靠的(我怎么能真正知道延迟多长时间?)。

stringByEvaluatingJavaScriptFromString 是在线程上完成的,我是否正确,我无法判断它何时完成?有关如何解决此问题的任何其他建议?

编辑:简而言之,我想知道是否可以在执行stringByEvaluatingJavaScriptFromString 时禁用UIWebView,并在javascript 运行时重新启用UIWebView完成了。

编辑 2: 这里有一篇文章似乎暗示您可以以某种方式轮询 JS 引擎以查看它何时完成,但我找不到任何其他参考资料说同样的话:@987654321 @

EDIT 3 根据 Brad Smith 的回答,似乎我实际上需要知道 UIWebView 在 javascript 执行后何时完成自身加载。它看起来越来越像我只需要在那里放一个延迟。

【问题讨论】:

  • 同样的问题!你的解决方案是什么?
  • 我认为我不得不仅仅假设这需要一定的时间,并将我的处理延迟至少该时间。
  • 同样的问题。哎呀,必须有更好的方法来做到这一点。
  • 你能给出一些示例代码吗?仅凭您的描述就有点难以理解。顺便说一句,javascript 是单线程的;浏览器使用任务调度器(参见 setTimeout())来模拟多个线程。据我所知,stringByEvaluatingJavaScriptFromString 的行为是异步的(将一些逻辑/功能委托给任务调度程序),并且您希望它的行为是同步的(防止它在每个函数执行之前返回)。

标签: javascript iphone uiwebview


【解决方案1】:

您可以将要注入到页面中的 javascript 尝试在其他地方导航页面 (document.location="foo"),然后使用 webView:ShouldLoadRequest: 来查找该请求并返回 no 以及触发什么你需要(并且通常返回是)。

【讨论】:

  • 遗憾的是,这似乎对我不起作用。我在我注入的 javascript 的最后添加了 document.location 调用,但这似乎仍然在退出按钮消失之前被调用。好像 JS 已经运行过了,但是 WebView 还没有处理完变化。
【解决方案2】:

stringByEvaluatingJavascriptFromString 必须在它返回时完成。它可能在不同的线程上完成(可能不会,因为它可以更改 UI),但该方法在有结果要返回之前无法返回字符串结果。

【讨论】:

  • 是的,我意识到在 webview 返回之前无法完成 javascript。请查看我编辑的问题以澄清我在问什么。
【解决方案3】:

执行 stringByEvaluatingJavascriptFromString 后,你可以试试下面的代码来解决你的问题

webView.userInteractionEnabled = NO;
while (webView.loading) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
webView.userInteractionEnabled = YES;

让我知道它是否适合你。

【讨论】:

    【解决方案4】:

    如何在 html 元素上直接为 onclick 事件内联存根函数。您可以稍后在更合适的时候将 html 元素绑定到 onclick 事件处理函数。

    <button onclick="function () { };"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多