swift - iOS14,WKWebView 无法打开带有 _blank 目标的链接
问题描述
我有 WKWebView,我想用它来浏览某个网站。
然而,一些带有 target="_blank" 的链接并不总是打开。从运行到运行,我得到不同的结果。
任何想法都将受到高度赞赏。
这是我的代码。WebViewStore 由 SwiftUI 视图使用,这就是它是 ObservableObject 的原因。
public class WebViewStore: NSObject, ObservableObject {
@Published public var navDelegate = WebViewNavDelegate();
@Published public var uiDelegate = WebViewUIDelegate();
@Published public var webView: WKWebView = WKWebView() {
didSet {
log.info("WebViewStore.webView new WebView !!!")
setupObservers()
}
}
override public init() {
super.init();
log.info("WebViewStore.init")
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
configuration.preferences = preferences
let webView = WKWebView(frame: CGRect.zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.allowsLinkPreview = true
webView.allowsBackForwardNavigationGestures = true
webView.isUserInteractionEnabled = true
webView.uiDelegate = uiDelegate;
webView.navigationDelegate = navDelegate;
self.webView = webView;
}
这是仅对某些链接调用的 navDelegate!
public class WebViewNavDelegate : NSObject, WKNavigationDelegate, ObservableObject {
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
log.info("WebViewUI.webView : 6 - decidePolicyFor" )
isLoading = true;
log.info("url: \(navigationAction.request.url!.absoluteString)")
log.info("target: \(navigationAction.targetFrame?.description)")
// This allows the navigation
decisionHandler(.allow)
}
}
这是我的 uiDelegate。我希望在需要新视图时调用它,我会将它加载到原始视图中(相同)。
不幸的是,这个方法只是有时被调用......
public class WebViewUIDelegate : NSObject, WKUIDelegate {
public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
log.info("WebViewUIDelegate.webView() (createWebViewWith)")
log.info("url: \(navigationAction.request.url?.absoluteString)" )
log.info("target: \(navigationAction.targetFrame)" )
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
}
解决方案
这不是最终的解决方案,但它以某种方式起作用。感谢WKWebView 没有打开 SOME target="_blank" 链接(5 岁的黑客)
很明显,在撰写本文时,WKWebView 在解析 href 标签的 _blank 目标属性时存在一些“未知”错误。
这个想法是在运行时“破解”加载的 html 代码并将所有 _blank 值替换为 _self。这将强制 WKWebView 将 _blank 链接加载到自身中。
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
let jsCode = "var allLinks = document.getElementsByTagName('a');if (allLinks) { var i;for (i=0; i<allLinks.length; i++) {var link = allLinks[i];var target = link.getAttribute('target');if (target && target == '_blank') {link.setAttribute('target','_self');} } }"
webView.evaluateJavaScript(jsCode, completionHandler: nil)
}
推荐阅读
- time - 正确的CUDA程序执行时间
- firebase - 无法在 Firestore onCreate Cloud 函数中获取所有文档
- java - 如何在文本区域打印文件内容?
- angular - Angular7+,*ngFor 每行 X 数量的项目,最佳实践
- javascript - 使用角度和节点设置代理时出现问题
- javascript - 在折线图顶部显示值
- python - Google Colab 上的深度学习:加载大型图像数据集很长,如何加速这个过程?
- excel - Excel VBA循环遍历outlook html中的所有超链接并复制到excel
- python - Python - 替换字符串中的所有单词,除了一些
- arm - ARM SVE 从左到右与树减少