您的位置:首页 > 移动开发

WKWebView遇到_blank的处理方法

2018-01-16 11:23 1086 查看
hihi,勇敢的小伙伴们大家好~

昨天用WKWebView加载百度网页,查了一下罗罗诺亚·索隆,点进百度百科,再点蓝色超链接,就发现打开词条不好用,用safari对比测试,发现原来默认打开一个新的窗口,嗯,那么问题来了~

以下原文:

WKWebView重构了webView给开发者带来更多灵活性同时,也会出现一些初看起来莫名其妙的问题。
_blank 就是其中之一


本文讨论的是当html源代码中,一个可点击的标签带有 target='_blank' 时,导致WKWebView无法加载点击后的网页的问题。

如果你发现你的WKWebView中的网页,点击某个按钮无反应。就看看这个吧。


问题出现的原因

_blank 标签,众所周知,是让浏览器新开一个页面来打开链接,而不是在原网页上打开。

在UIWebView上,只有一个页面,所以会自动在原来的页面上打开新链接。

但是在WKWebView上就不是这样了。
WKWebView 的 WKNavigationDelegate 有一个
-(void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
方法。用户点击网页上的链接,需要打开新页面时,将先调用这个方法。

这个方法的参数 WKNavigationAction 中有两个属性:sourceFrame和targetFrame,分别代表这个action的出处和目标。类型是 WKFrameInfo 。WKFrameInfo有一个 mainFrame 的属性,正是这个属性标记着这个frame是在主frame里还是新开一个frame。
如果 targetFrame 的 mainFrame 属性为NO,表明这个 WKNavigationAction 将会新开一个页面。
WKWebView遇到这种情况,将会调用 它的 WKUIDelegate 代理中的
-(nullable WKWebView*)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
方法。
开发者实现这个方法,返回一个新的WKWebView,让WKNavigationAction在新的webView中打开。如果你没有设置WKUIDelegate代理,或者没有实现这个协议。那么WKWebView将什么事情都不会做,也就是你点那个按钮没反应。
注意:返回的这个WKWebView不能和原来的WKWebView是同一个。如果你返回了原来的webView,将会抛出异常。


解决办法

apple设置这个协议的作用就是要求开发者新开一个webView。但实际使用中,我们的应用中webView也就拿来简简单单显示网页罢了,写那么复杂没必要。
所以解决办法1:
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
WKFrameInfo *frameInfo = navigationAction.targetFrame;
if (![frameInfo isMainFrame]) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
这样处理的话,相当于放弃掉原来的点击事件,强制让webView加载打开的链接。
原来我就是这么做的,直到:http://www.soku.com/m/y/video?q=阿凡达%20片段#loaded这个优酷链接。

这个链接里,点击某个视频,将会新开页面打开。然后在这个协议方法里,navigationAction.request 竟然是空的!request的URL是空的!
所以解决办法2:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
if (!navigationAction.targetFrame.isMainFrame) {
[webView evaluateJavaScript:@"var a = document.getElementsByTagName('a');for(var i=0;i<a.length;i++){a[i].setAttribute('target','');}" completionHandler:nil];
}
decisionHandler(WKNavigationActionPolicyAllow);
}
一劳永逸(真的有一劳永逸的方法吗)···
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: