alert() 在 WKWebview 中不起作用 evaluateJavaScript()

Posted

技术标签:

【中文标题】alert() 在 WKWebview 中不起作用 evaluateJavaScript()【英文标题】:alert() not working in WKWebview evaluateJavaScript() 【发布时间】:2017-04-25 02:33:18 【问题描述】:

我不知道为什么我的问题被标记为 this one 的重复,首先我使用 evaluatejavascript 执行 javascript 代码,因为问题标题显示它与该问题明显不同。更重要的是,我注意到我在问题正文的末尾尝试了该问题的答案,但没有成功。

我使用wkwebview.evaluateJavaScript()函数在swift3的wkwebview中执行javascript。但是alert() 没有打开警报对话框。并且没有错误和问题显示。虽然我可以使用evaluateJavaScript() 执行javascript 代码来修改页面内容。

class WebViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate 
    var wk:WKWebView!
    self.wk.navigationDelegate = self
    self.wk.uiDelegate = self
    self.wk.scrollView.delegate = self
    self.wk.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0"

    ...
    override func viewDidLoad() 
        super.viewDidLoad()
        ...
        let config = WKWebViewConfiguration()
        self.wk = WKWebView(frame: CGRect(x: frame.minX, y: frame.minY+20, width: frame.width, height: frame.height-70), configuration: config)
        self.wk.navigationDelegate = self
        ...
    


    ...
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) 
        print("Finished navigation to url \(String(describing: webView.url))")
        //self.wk.evaluateJavaScript("document.getElementById('test').innerhtml = 'sssssssssssssss';", completionHandler: nil)          //this works well
        self.wk.evaluateJavaScript("alert('aaaaaaa');", completionHandler: nil)     //this not show the alert dialog
    
    ...

我也参考了这个post 和answer,而这个问题不在评估JavaScript 上。我为我的WebViewController 添加WKUIDelegate 并将self.wk.uiDelegate = self 添加到我的viewDidLoad(),但没有任何变化。

补充说,console.log() 下方将日志放在控制台中,而alert() 不会弹出对话框。 UIAlertController 也可以工作。

self.wk.evaluateJavaScript("alert('aa');console.log('1234');var rect = document.getElementById('liveMovie').getBoundingClientRect();[rect.left, rect.top];") 
    (result, error) -> Void in
    if((result) != nil)
    
        self.player?.view?.frame.origin.x = (result as! Array)[0]
        self.player?.view?.frame.origin.y = (result as! Array)[1]
    


let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler:  (action) in
     if(true)
     
     
))

【问题讨论】:

您没有提到runJavaScriptAlertPanelWithMessage 委托方法。可以将该代码添加到您的问题中吗? 我没有在我的代码中使用那个方法。 UIAlertController 可以在我的代码中工作,但 evaluateJavaScript 不能 alert() 这就是为什么它不起作用的原因。当 javascript 触发和alert() 时调用此方法。然后由您决定如何处理它。请参阅下面链接的答案中的示例。 总结 Onato 的意思:链接的问题 is 相关。流程是这样的:您使用alert() 评估JS,这会触发webview 调用其委托的runJavaScriptAlertPanelWithMessage。如果没有实施,警报将不会打开。无论您是从传递给 evaluateJavaScript 的东西中调用 JS alert() 还是站点调用它本身(即它已经在其代码中)都无关紧要。我想知道为什么你会相信有区别? @KrisRoofe 没问题,一切都好。只是想确保您得到解决方案(并且当之无愧的接受 Onato)。 :) WKWebView 在某些地方确实仍然有点奇怪(比 UIWebView 更强大,但遗憾的是仍然没有完成所有事情)所以它可能会令人困惑。 【参考方案1】:

this answer 中有一个工作示例。看来您可能没有正确实现 WKUIDelegate 方法。

【讨论】:

【参考方案2】:

首先您需要实现所需的 WKUIDelegate 方法,在您的情况下您需要实现:

optional func webView(_ webView: WKWebView, 
    runJavaScriptAlertPanelWithMessage message: String, 
         initiatedByFrame frame: WKFrameInfo, 
        completionHandler: @escaping () -> Void)

    // parameter **message** will hold your actual alert message.

    // Write Your Customised code to display the alert message

【讨论】:

【参考方案3】:

这是我的错。我对WKWebview 没有太多经验。我有使用androidXWalkview的经验,执行alert不需要用java代码实现alert。所以在这里我也错过了我不需要用swift实现alertdelegate的想法。

answer of Onato,我了解到如何快速执行alert promptconfirm,我失去了这些委托的实现。所以我参考this answer,添加下面的实现,一切正常。

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
             completionHandler: @escaping () -> Void) 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler:  (action) in
        completionHandler()
    ))

    present(alertController, animated: true, completion: nil)



func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
             completionHandler: @escaping (Bool) -> Void) 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)

    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler:  (action) in
        completionHandler(true)
    ))

    alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler:  (action) in
        completionHandler(false)
    ))

    present(alertController, animated: true, completion: nil)



func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo,
             completionHandler: @escaping (String?) -> Void) 

    let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .actionSheet)

    alertController.addTextField  (textField) in
        textField.text = defaultText
    

    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler:  (action) in
        if let text = alertController.textFields?.first?.text 
            completionHandler(text)
         else 
            completionHandler(defaultText)
        
    ))

    alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler:  (action) in
        completionHandler(nil)
    ))

    present(alertController, animated: true, completion: nil)

【讨论】:

以上是关于alert() 在 WKWebview 中不起作用 evaluateJavaScript()的主要内容,如果未能解决你的问题,请参考以下文章

在 WKWebView 中加载本地文件在设备中不起作用

navigator.notification.alert 在 iOS 9 中不起作用

UIATarget.onAlert 在 Instruments 5.0 中不起作用?

reCAPTCHA 在 iOS 10 UIWebView 中不起作用

视频在本机反应(android)中不起作用

charAt() 在 JavaScript 中不起作用