确定stringByEvaluatingJavaScriptFromString何时完成

13
我有一个UIWebView,它加载了一个HTML页面。这个页面上有两个按钮,分别是Exit和Submit。我不希望用户能够点击Exit按钮,因此一旦页面加载完成(即调用webViewDidFinishLoad),我使用stringByEvaluatingJavaScriptFromString来通过操纵HTML删除其中一个按钮。在webViewDidStartLoad时我还会禁用UIWebView的用户交互,在webViewDidFinishLoad上重新启用它。
我遇到的问题是stringByEvaluatingJavaScriptFromString需要一两秒钟才能完成,而且似乎是在自己的线程中进行的。所以正在发生的情况是,webViewDidFinishLoad被调用,UIWebView的用户交互被启用,如果用户很快就可以在stringByEvaluatingJavaScriptFromString完成之前单击Exit按钮。由于stringByEvaluatingJavaScriptFromString似乎在自己的线程上没有方法可知道何时完成(它不调用webViewDidFinishLoad),我唯一看到完全防止用户点击Exit按钮的方法是延迟一段时间后再启用UIWebView的用户交互,但这种方法是不可靠的(我怎么知道延迟多久?)。
我是否正确,stringByEvaluatingJavaScriptFromString在它自己的线程上运行,并且我无法知道它何时完成?还有其他建议如何解决这个问题吗?
编辑:简而言之,我想知道是否可能在stringByEvaluatingJavaScriptFromString执行时禁用UIWebView,并在javascript执行完成后重新启用UIWebView

编辑2: 这里有一篇文章似乎在暗示你可以以某种方式轮询JS引擎,以检测何时完成,但我找不到任何其他表明同样事情的参考资料:http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/

编辑3: 根据Brad Smith的回答,似乎我实际上需要知道当javascript执行完毕后,UIWebView何时完成加载自身。看起来我只需要加入某种延时。


2
这里也有同样的问题!你的解决方案是什么? - Renato Lochetti
我相信我只能假设它需要一定的时间,并至少将我的处理延迟该时间。 - Ben Williams
1
同样的问题。哎呀,一定有更好的方法来解决这个问题。 - Matt Mc
你能给一些示例代码吗?仅凭你的描述已经有点难以理解了。顺便说一下,JavaScript 是单线程的;浏览器使用任务调度程序(参见 setTimeout())来模拟多个线程。从我所知道的,stringByEvaluatingJavaScriptFromString 表现得异步(将某些逻辑/函数委托给任务调度程序),而你希望它表现得同步(在每个函数执行之前防止其返回)。 - dot slash hack
4个回答

2
执行stringByEvaluatingJavascriptFromString后,您可以尝试以下代码来解决您的问题。
webView.userInteractionEnabled = NO;
while (webView.loading) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
webView.userInteractionEnabled = YES;

请告诉我它是否对您有效。


2

如何在HTML元素中直接内联一个存根函数来处理onclick事件呢?当更合适的时候,您可以将该HTML元素绑定到一个onclick事件处理程序函数。

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

2

您可以将您注入页面的JavaScript尝试导航到其他地方(document.location="foo"),并使用webView:ShouldLoadRequest:查找该请求并返回no,以及触发所需内容(通常返回yes)。


很遗憾,这对我似乎不起作用。我在注入的JavaScript的最后添加了document.location调用,但这似乎仍然在退出按钮消失之前被调用。看来JS已经运行了,但WebView还没有完成处理更改。 - Ben Williams

2

当stringByEvaluatingJavascriptFromString方法返回时,必须执行它。它可能在不同的线程上执行(可能不会,因为它可以改变UI),但是该方法只有在有结果可返回时才能返回字符串结果。


是的,我意识到在 webview 返回之前无法完成 JavaScript。请查看我编辑过的问题以澄清我的问题。 - Ben Williams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接