我正在使用WKWebView
来显示一个网站,该网站的HTML包含三个按钮。单击特定按钮后,我想在本机应用程序中运行一些Swift代码。
三个按钮如下所示:
<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
函数如下:
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!) {
// ...?
}
但是,navigation
当然是不透明的,因此不包含有关用户单击了三个按钮中的哪个按钮的信息。
我想在用户单击提交并忽略其他按钮按下时做出响应。
我在使用WKUserContentController
的Stack Overflow上看到了其他一些方法,但是它们似乎要求网站调用类似的内容:
window.webkit.messageHandlers.log.postMessage("submit");
我无法控制该网站,因此无法在其源代码中添加此行,并且我不知道使用WKWebView
将其注入正确位置的最佳方法。
答案 0 :(得分:2)
您始终可以在网络视图上使用evaluateJavaScript(_:)
注入源代码。从那里,替换按钮上的事件处理程序(发布消息,然后在新处理程序中调用原始函数),或者在按钮上添加事件处理程序或捕获点击事件并发布消息的祖先元素。 (原始事件处理程序也将运行。)
document.getElementById("submit-button").addEventListener("click", function () {
window.webkit.messageHandlers.log.postMessage("submit");
});
如果按钮没有ID,则可以在文档上添加一个处理程序,以捕获所有(冒泡)单击事件,然后根据事件目标发布消息(使用按钮的文本或位置作为决定因素)
答案 1 :(得分:2)
您可以使用 evaluateJavaScript()
函数向WKWebView
注入JS代码。您可以使用以下JS代码捕获所有onclick
事件,该事件仅检测单击submit
按钮的情况。所有原始事件处理程序也将运行-不用担心!
document.addEventListener("click", function(e)
{
e = e || window.event;
//if(e.target.value == 'Submit') //you can identify this button like this, but better like:
if(e.target.getAttribute('onclick') == 'javascript:GotoURL(3)')
//if this site has more elements with onclick="javascript:GotoURL(3)"
//if(e.target.value == 'Submit' && e.target.getAttribute('onclick') == 'javascript:GotoURL(3)')
{
console.log(e.target.value);
//if you need then you can call the following line on this place too:
//window.webkit.messageHandlers.log.postMessage("submit");
}
});
//DO NOT add the next line in your code! It is only for my demo - buttons need this in my demo for execution
function GotoURL(site){}//DO NOT add this line! It is only for my demo!
<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)">
答案 2 :(得分:0)
这里是详细的实现:
var webView: WKWebView?
var webConfig:WKWebViewConfiguration {
get {
let webCfg:WKWebViewConfiguration = WKWebViewConfiguration()
let userController:WKUserContentController = WKUserContentController()
userController.add(self, name: "submit")
let js:String = buttonClickEventTriggered()
let userScript:WKUserScript = WKUserScript(source: js, injectionTime:WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
userController.addUserScript(userScript)
webCfg.userContentController = userController;
return webCfg;
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.webView = WKWebView(frame: self.view.frame, configuration: webConfig)
self.webView!.navigationDelegate = self
self.view = webView!
let url = URL(string:"your URL here")
let req = NSURLRequest(url:url! as URL)
self.webView!.load(req as URLRequest)
}
func buttonClickEventTriggered() ->String{
let script:String = "document.getElementById('your button id here').addEventListener('click', function () {window.webkit.messageHandlers.submit.postMessage('submited');});"//Make sure you have mapped the name correctly under userController.add
return script;
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("Sucessss")
if(message.name == "submit") {
print("It does ! \(message.body)")
// Your code goes here
}
}