如何使用iOS WKWebView注入JavaScript回调以检测onclick事件? [英] How to inject JavaScript callback to detect onclick event, using iOS WKWebView?

查看:148
本文介绍了如何使用iOS WKWebView注入JavaScript回调以检测onclick事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 WKWebView 来显示一个网站,该网站的HTML包含三个按钮.单击特定按钮后,我想在本机应用程序中运行一些Swift代码.

I'm using a WKWebView to show a website which has some HTML that includes three buttons. I want to run some Swift code in the native app when a specific button is clicked.

三个按钮如下所示:

<input type="button" value="Edit Info" class="button" onclick="javascript:GotoURL(1)">
<input type="button" value="Start Over" class="button" onclick="javascript:GotoURL(2)">
<input type="button" value="Submit" class="button" onclick="javascript:GotoURL(3)">

他们调用的 GotoURL 函数如下所示:

The GotoURL function they call looks like this:

function GotoURL(site)
{
    if (site == '1')
        document.myWebForm.action = 'Controller?op=editinfo';
    if (site == '2')
        document.myWebForm.action = 'Controller?op=reset';
    if (site == '3')
        document.myWebForm.action = 'Controller?op=csrupdate';
    document.myWebForm.submit();
}

当前 WKWebView 实现

当我单击Web视图中的任何按钮时,将在我的 WKNavigationDelegate 上调用此函数:

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    // ...?
}

但是,当然,导航是不透明的,因此不包含有关用户单击了三个按钮中的哪个按钮的信息.

But of course, navigation is opaque and therefore contains no information about which of the three buttons the user clicked.

我想在用户单击提交而忽略其他按钮按下时做出响应.

I want to respond when the user clicks Submit and ignore other button presses.

我在使用 WKUserContentController 的Stack Overflow上看到了其他一些方法,但是它们似乎要求网站调用类似的内容:

I see some other approaches on Stack Overflow using WKUserContentController, but they appear to require the web site to call something like:

window.webkit.messageHandlers.log.postMessage("submit");

我不控制此网站,因此无法在其源代码中添加此行,并且我不知道使用 WKWebView 将其注入正确位置的最佳方法.

I do not control this website so I cannot add this line in its source code, and I don't know the best way to inject it in the correct place using WKWebView.

推荐答案

用户脚本是您在文档加载开始时或文档加载完成后注入到网页中的JS.用户脚本非常强大,因为它们允许客户端自定义网页,允许注入事件侦听器,甚至可以用来注入脚本,这些脚本又可以回调到本机应用程序中.以下代码段创建了一个用户脚本,该文档在文档加载结束时注入.用户脚本将添加到WKUserContentController实例中,该实例是WKWebViewConfiguration对象的属性.

User Scripts are JS that you inject into your web page at either the start of the document load or after the document is done loading. User scripts are extremely powerful because they allow client-side customization of web page, allow injection of event listeners and can even be used to inject scripts that can in turn call back into the Native app. The following code snippet creates a user script that is injected at end of document load. The user script is added to the WKUserContentController instance that is a property on the WKWebViewConfiguration object.

// Create WKWebViewConfiguration instance
  var webCfg:WKWebViewConfiguration = WKWebViewConfiguration()

  // Setup WKUserContentController instance for injecting user script
  var userController:WKUserContentController = WKUserContentController()

  // Get script that's to be injected into the document
  let js:String = buttonClickEventTriggeredScriptToAddToDocument()

  // Specify when and where and what user script needs to be injected into the web document
  var userScript:WKUserScript =  WKUserScript(source: js, 
                                         injectionTime: WKUserScriptInjectionTime.atDocumentEnd,
                                         forMainFrameOnly: false)

  // Add the user script to the WKUserContentController instance
  userController.addUserScript(userScript)

  // Configure the WKWebViewConfiguration instance with the WKUserContentController
  webCfg.userContentController = userController;

您的网页可以通过 window.webkit.messageHandlers.< name> .postMessage(< message body>)方法将消息发布到您的本机应用程序.此处,名称"是要回发的消息的名称.JS可以将任何JS对象作为消息正文发回,并且JS对象将自动映射到相应的Swift本机对象.以下JS代码段在ID为"ClickMeButton"的按钮上发生按钮单击事件时回发消息.

Your web page can post messages to your native app via the window.webkit.messageHandlers.<name>.postMessage (<message body>) method. Here, "name" is the name of the message being posted back. The JS can post back any JS object as message body and the JS object would be automatically mapped to corresponding Swift native object. The following JS code snippet posts back a message when a button click event occurs on a button with Id "ClickMeButton".

var button = document.getElementById("clickMeButton");
button.addEventListener("click", function() {
            varmessageToPost = {'ButtonId':'clickMeButton'};
            window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);
        },false);

为了接收您的网页发布的消息,您的本机应用程序需要实现WKScriptMessageHandler协议.该协议定义了一个必需的方法.可以查询在回调中返回的WKScriptMessage实例,以获取有关回发的消息的详细信息.

In order to receive messages posted by your web page, your native app needs to implement the WKScriptMessageHandler protocol. The protocol defines a single required method. The WKScriptMessage instance returned in the callback can be queried for details on the message being posted back.

func userContentController(userContentController: WKUserContentController,
                           didReceiveScriptMessage message: WKScriptMessage) {

        if let messageBody:NSDictionary= message.body as? NSDictionary{
            // Do stuff with messageBody
        }

    }

最后,实现WKScriptMessageHandler协议的本机类需要通过WKWebView将自身注册为消息处理程序,如下所示:

Finally, the native class that implements WKScriptMessageHandler protocol needs to register itself as a message handler with the WKWebView as follows:

// Add a script message handler for receiving  "buttonClicked" event notifications posted 
// from the JS document
userController.addScriptMessageHandler(self, name: "buttonClicked")

这篇关于如何使用iOS WKWebView注入JavaScript回调以检测onclick事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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