如果您的 webview 额外加载了正文的一部分(或整个 html 正文),那么通过在方法内部评估您的 javascript,您将不会获得所需的结果:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
这样做的原因是,一旦在 webview 内完成导航,就会调用“didFinish”方法,但不是严格在加载 webView 内可能处于状态的整个内容之后:
- 状态:身体空虚
- 状态:一些加载
- 状态:javascript框架完成了他的工作并在里面插入了app-body
- 状态:正文有内容
在状态 1 中调用“didFinish”。您可以使用 DispatchQueue.main.asyncAfter 等待一段时间,然后执行 .evaluateJavascript 但它会使 webView 在用户面前进行更改(我认为这很丑......)
我的建议是这个扩展:
extension WKWebView {
// it re-execute javascript in cases when body is attached additionally on the html by some inner javascript framework
// it tries around 50 times maximum in time range of 10 sec
// if body is not loaded in 10 secs, this won't work
func rexecuteJavascript(tryouts: Int = 0, script: String) {
self.evaluateJavaScript(script, completionHandler: { (result: Any?, error: Error?) in
if let _ = error, tryouts < 50 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
return self.rexecuteJavascript(tryouts: tryouts + 1, script: script)
}
}
})
}
}
它对我来说非常有效,因为在“didFinish”之后大约 2-3 秒内填充了 webview 的主体,我使用它在完全加载的主体上执行我的 javascript:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let removeFooterScript = "document.getElementsByClassName('global-footer')[0].style.display='none';"
webView.rexecuteJavascript(script: removeFooterScript)
}
干杯!