I have loaded a webpage into a WKWebView
. I want to detect when the user clicks this specific button.
<div class="compacted-item">
<button class="btn btn-lg btn-primary deploy-button" data-ember-action="1361">
Deploy
</button>
</div>
decidePolicyFor navigationAction
isn't triggered because it's not a navigation action.
I know how to add a js message handler to the web views user content controller, but since I don't own the webpage, how do I get it to send off a message for me to intercept? Such as:
window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);
Or is there another way to detect non-navigation button clicks in a WKWebView
?
This is technically possible, but you have to get a little hacky to do it. You can inject arbitrary js into a WKWebView, so you can find the element and add an event listener to it. Of course, you run the risk that someone will change the html out from under you and your functionality might break at that point.
I threw together a quick and dirty example project to try it out (I just threw your button into a hard-coded html document). Here's the gist of how to do this. (Note, this is a really quick and dirty implementation and JS isn't really my strong suit, but you definitely want to refine this and at least make sure your query has some results before you start accessing them like I did.). In your implementation of WKScriptMessageHandler
, you can do whatever you need to once you receive the message from your injected script.
class ViewController: UIViewController {
...
private func getConfiguredWebview() -> WKWebView {
let config = WKWebViewConfiguration()
let js = "document.querySelectorAll('.deploy-button')[0].addEventListener('click', function(){ window.webkit.messageHandlers.clickListener.postMessage('Do something'); })"
let script = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
config.userContentController.addUserScript(script)
config.userContentController.add(self, name: "clickListener")
let webView = WKWebView(frame: .zero, configuration: config)
return webView
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.body)
}
}
This answer was inspired by https://learnappmaking.com/wkwebview-how-to/ this page.
Also, sorry about resurrecting a really old post hopefully it helps someone. To be honest, I looked at the question and not the date, then got a little carried away figuring out if it was possible or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With