如何检测WKWebView中的哈希变化?

时间:2017-08-23 16:57:19

标签: swift macos hash wkwebview

我有一个网站使用javascript,使用角度来控制你在网站上看到的内容。因此,会显示http://somewebsite.com/#page1,当您点击某个位置更改为http://somewebsite.com/#page2的标签时。网站上没有实际的重新加载,因此func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)将不会被触发。你怎么能抓住这些哈希变化?

很明显Apple可以,因为Safari webbrowser能够在位置栏中显示这些变化。

更新19.33:

我做了一些研究。在Safari浏览器中使用window.onhashchange这将被解雇,但是在WKWebView中却没有。深入潜水我使用以下javascript每秒返回文档位置href。

window.setInterval(function(){ alert(document.location) }, 1000);

在WKWebView中读取该警报时,它永远不会显示位置发生变化,而在Safari中,您会看到http://somewebsite.com/#page1http://somewebsite.com/#page2。看起来WKWebView不支持这个非常烦人的功能。

2 个答案:

答案 0 :(得分:1)

let script = WKUserScript(source: "(function() { \"use strict\"; addEventListener(\"hashchange\", function(event) { webkit.messageHandlers.hashchangeMessageHandler.postMessage(null); }); }) ();", injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)

let configuration = WKWebViewConfiguration()
configuration.userContentController.add(self, name: "hashchangeMessageHandler")
configuration.userContentController.addUserScript(script)

self.webView = WKWebView(frame: CGRect.zero, configuration: configuration)

现在您可以使用以下命令获取散列更改的URL:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print("Received message: \(message.name): \(message.body)")
    print(self.webView.url)

}

答案 1 :(得分:0)

无需注入任何JS。我使用了webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil),它正在检测所有URL更改,包括哈希更改。然后:

override func observeValue(
    forKeyPath keyPath: String?,
    of object: Any?,
    change: [NSKeyValueChangeKey: Any]?,
    context: UnsafeMutableRawPointer?) {
  if object as AnyObject? === webView && keyPath == "URL" {
    onURLChange(webView.url) // onURLChange does whatever you want
  }
}

不要忘记在webView.removeObserver(self, forKeyPath: "URL")块中deinit