如何使用iOS WKWebView注入JavaScript回调来检测onclick事件?

Aar*_*ger 16 javascript ios swift wkwebview

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

关于HTML

这三个按钮看起来像这样:

<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)">
Run Code Online (Sandbox Code Playgroud)

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

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();
}
Run Code Online (Sandbox Code Playgroud)

目前的WKWebView实施

当我单击webview中的任何按钮时,在我的上面调用此函数WKNavigationDelegate:

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    // ...?
}
Run Code Online (Sandbox Code Playgroud)

但当然,它navigation是不透明的,因此不包含用户点击的三个按钮中的哪一个的信息.

检测单击此按钮的最简单方法是什么?

我想在用户单击" 提交"时进行响应,并忽略其他按钮按下.

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

window.webkit.messageHandlers.log.postMessage("submit");
Run Code Online (Sandbox Code Playgroud)

我不控制这个网站所以我不能在它的源代码中添加这一行,我不知道使用它在正确的地方注入它的最佳方法WKWebView.

Kou*_*sic 8

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

// 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;
Run Code Online (Sandbox Code Playgroud)

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

varbutton = document.getElementById("clickMeButton");
button.addEventListener("click", function() {
            varmessageToPost = {'ButtonId':'clickMeButton'};
            window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);
        },false);
Run Code Online (Sandbox Code Playgroud)

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

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

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

    }
Run Code Online (Sandbox Code Playgroud)

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

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


Con*_*has 5

您始终可以evaluateJavaScript(_:)在 Web 视图上使用注入源代码。从那里,要么替换按钮上的事件处理程序(发布一条消息,然后在新的处理程序中调用原始函数),要么在按钮上添加一个事件处理程序,或者添加一个捕获点击事件并发布一条消息的祖先元素。(原始事件处理程序也将运行。)

document.getElementById("submit-button").addEventListener("click", function () {
   window.webkit.messageHandlers.log.postMessage("submit");
});
Run Code Online (Sandbox Code Playgroud)

如果按钮没有 ID,您可以在文档上添加一个处理程序来捕获所有(冒泡)点击事件,然后根据事件目标发布消息(使用按钮的文本或位置作为决定因素)。