0

I am trying to run a javascript command that works if I run it in the console on the web. I have tried doing the code below, but I keep getting nil as my response.

webView.evaluateJavaScript("command") { (result, error) in
     if error == nil {
          print(result)
     } else {
          print(error)
     }
}
4

2 回答 2

0

这是在 WKWebView 中注入 javascript 代码的代码

let wkUScript = WKUserScript(source: "your javascript command",
                             injectionTime: .atDocumentEnd,
                             forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(wkUScript)

let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController

let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: 400, height: 400), configuration: wkWebConfig)
于 2020-08-10T06:58:37.797 回答
0

如果您的 webview 额外加载了正文的一部分(或整个 html 正文),那么通过在方法内部评估您的 javascript,您将不会获得所需的结果:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) 

这样做的原因是,一旦在 webview 内完成导航,就会调用“didFinish”方法,但不是严格在加载 webView 内可能处于状态的整个内容之后:

  1. 状态:身体空虚
  2. 状态:一些加载
  3. 状态:javascript框架完成了他的工作并在里面插入了app-body
  4. 状态:正文有内容

在状态 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)
}

干杯!

于 2021-04-20T03:31:03.130 回答