在带有Java脚本的WKWebView中检测按钮点击(按类名)。评估 [英] Detect button click (by class name) in WKWebView with JavaScript.evaluate

查看:30
本文介绍了在带有Java脚本的WKWebView中检测按钮点击(按类名)。评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试为用户在WKWebView中单击此按钮元素时添加侦听器:

<div class="web-navigation__auth" data-test-web-chrome-auth="">
    <button class="web-navigation__auth-button web-navigation__auth-button--sign-in button button-reset button--auth">
        <svg ... ></path></g></svg>
        Sign In
    </button>

    <div class="web-chrome-auth-container__spinner web-chrome-auth-container__spinner--hidden"></div>
</div>

我尝试使用许多不同的JavaScript评估进行观察,并在不同的地方(即.viewDidLoadwebView(didFinish)webView(didStartProvisionalNavigation)等):

let js1 = "document.addEventListener('click', function(e) { e = e || window.event; if(e.target.getAttribute('class') == 'web-navigation__auth-button') { console.log(e.target.value); } });"
let js2 = "var elements = document.getElementsByClassName('web-navigation__auth'); var myFunction = function() { var attribute = this.getAttribute('web-navigation__auth-button--sign-in'); alert(attribute); }; for (var i = 0; i < elements.length; i++) { elements[i].addEventListener('click', myFunction, false); }"
let js3 = "document.addEventListener('click', getElementsByClassName('web-navigation__auth-button').onclick();"

webView.evaluateJavaScript(js) { (key, err) in
    if let err = err {
        print(err.localizedDescription)
    } else {
        print("JS: You tapped the Sign In button!")
    }
}

控制台的输出似乎只在调用webView.evaluateJavaScript时出现,而不是按下按钮时出现。除了下面关于js3的说明外,我获得按钮被按下时触发的任何代码。这是webView(didFinish)中每个JS调用的控制台输出:

js1: A JavaScript exception occurred     // on webView.didFinish
     JS: You tapped the Sign In button!  // on webView.didFinish

js2: A JavaScript exception occurred     // on webView.didFinish
     JS: You tapped the Sign In button!  // on webView.didFinish

js3: A JavaScript exception occurred     // on webView.didFinish
     A JavaScript exception occurred     // on Sign In button click (fired again)

关于js3需要注意的一点是,它将在webView.didFinish上触发错误消息,但如果按下按钮,也将触发错误。

所以从理论上讲,我可以创建一个标志来检查该按钮的点击情况;然而,我更喜欢比这个老套的解决方法更具体的方法:

// Error output to console on every new page load AND "Sign In" button click
var pageLoad = false    // Page has not yet loaded, false by default

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    pageLoad = true     // Page has loaded, unless new URL detected, next error = button click!
    if webView.urlHasChanged() { pageLoad = false }
    
    let js3 = "document.getElementsByClassName('web-navigation__auth-button').onclick();"
    webView?.evaluateJavaScript(js3) { (key, err) in
    if let err = err {  
        if pageLoad {
            // Error message && pageLoad = "Sign in" button pressed: CODE HERE
        }
    }
    if pageLoad && url.hasNotChanged() { pageLoad = false }
}

推荐答案

您可以通过将脚本消息处理程序添加到用户内容控制器并侦听

 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){}

下面是完整代码

class ViewController: UIViewController,WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {

    var webView: WKWebView!
    
    override func loadView() {
        webView = WKWebView()
        webView.navigationDelegate = self
        view = webView
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //Fetch html
        let url = URL(fileURLWithPath: Bundle.main.path(forResource: "example", ofType: "html") ?? "")
        let config: WKWebViewConfiguration = WKWebViewConfiguration()
        // Adding a script message handler
        config.userContentController.add(self, name: "test")
        webView = WKWebView(frame: self.view.frame, configuration: config)
        webView?.navigationDelegate = self
        webView.translatesAutoresizingMaskIntoConstraints = true
        webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.view.addSubview(self.webView)
        //Load html page
        self.webView?.loadFileURL(url, allowingReadAccessTo: Bundle.main.bundleURL)
    }

    // Delegate method on click action
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "test", let messageBody = message.body as? String {
            print(messageBody)
        }
    }

}

如下所示,您可以将示例HTML与Java脚本一起使用

<div id="test" style="height: 40px; width: 100px; background-color: powderblue;">Hello</div>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="js/platform.js"></script>

<script type="text/javascript">
document.getElementById("test").addEventListener("click", function test() {
    webkit.messageHandlers.test.postMessage("TEXT");
});
</script>

如果您正在寻找相同的产品,请让我知道。

这篇关于在带有Java脚本的WKWebView中检测按钮点击(按类名)。评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆