从 WKWebView 调用时,无法使用 JavaScript 在移动 Safari 中打开链接

Posted

技术标签:

【中文标题】从 WKWebView 调用时,无法使用 JavaScript 在移动 Safari 中打开链接【英文标题】:Cannot use JavaScript to open links in mobile Safari when called from WKWebView 【发布时间】:2016-10-26 00:31:57 【问题描述】:

This post 和this post 解决了在移动端Safari 中使用javascript 打开WKWebView 链接的问题,但是由于某种原因,提供的解决方案不起作用。

下面的代码合并了不同解决方案的元素,但点击按钮后仍然无法打开链接。

事实上,webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy)userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 甚至都不会被调用。

HTML:

<html>
    <style type="text/css">
        #button  width: 100px; height: 50px; background: red; 
    </style>

    <div id="button">CLICK TO GO</div>

    <script type="text/javascript">

    var button = document.getElementById("button");
    button.addEventListener("click", doTest);

    function doTest() 
        window.open("http://www.google.com", target="_blank");
        button.innerHTML = "HEY";
    

    </script>
</html>

视图控制器:

class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate 

    var webView: WKWebView?
    let webViewContentController = WKUserContentController()

    override func viewDidLoad() 
        super.viewDidLoad()

        let config = WKWebViewConfiguration()
        config.userContentController = webViewContentController

        webView = WKWebView(frame: view.bounds, configuration: config)

        webView!.navigationDelegate = self
        webView!.uiDelegate = self  //must have this

        var fileURL = URL(fileURLWithPath: Bundle.main.path(forResource:"Mooncake.html", ofType: nil)!)
        webView!.loadFileURL(fileURL, allowingReadAccessTo: fileURL)

        view.addSubview(webView!)
    

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 
    

    // this handles target=_blank links by opening them in the same view
    func webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView! 
        if navigationAction.targetFrame == nil 
            let url = navigationAction.request.url!
            let urlString = url.description.lowercased()

            if urlString.contains("http://") || urlString.contains("https://") || urlString.contains("mailto:") 
                UIApplication.shared.openURL(url)
            
        
        return nil
    

    func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) 
        if navigationAction.targetFrame == nil 
            webView.load(navigationAction.request)
        
    

【问题讨论】:

【参考方案1】:

问题在于使用过时的函数定义,从 SO 答案中提取,用于

webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView!

webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void)

使用类文档定义的 Swift 3 函数定义解决了这个问题。

【讨论】:

以上是关于从 WKWebView 调用时,无法使用 JavaScript 在移动 Safari 中打开链接的主要内容,如果未能解决你的问题,请参考以下文章

无法将文本从 WKWebview 复制到剪贴板

从 WKWebView 打印按钮单击 [重复]

WKwebview,js调用用Swift函数播放声音

WKWebview 导航响应方法在单击 webview 中的完成按钮时不会被调用

无法使用 WKWebView 在 Safari 中打开外部链接

如何使用嵌入视频从 WKWebView 截取屏幕截图?