首页
Javascript
Html
Css
Node.js
Electron

移动开发

小程序
工具类
服务端
浏览器相关
前端收藏
其他
关于
公司注册

WKWebView遇到_blank的处理方法

2019年01月16日 发布 阅读(3669) 作者:Jerman

问题描述 :iOS的WKWebView内核下,a链接带有target=”_blank”时,链接点不开


是时候迁移到WKWebView来了,github上兼容UIWebView的第三方浏览器也是一大把。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:

  1. - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
  2. {
  3. WKFrameInfo *frameInfo = navigationAction.targetFrame;
  4. if (![frameInfo isMainFrame]) {
  5. [webView loadRequest:navigationAction.request];
  6. }
  7. return nil;
  8. }

这样处理的话,相当于放弃掉原来的点击事件,强制让webView加载打开的链接。
原来我就是这么做的,直到:http://www.soku.com/m/y/video?q=阿凡达%20片段#loaded 这个优酷链接。
这个链接里,点击某个视频,将会新开页面打开。然后在这个协议方法里,navigationAction.request 竟然是空的!request的URL是空的!

所以解决办法2:

  1. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
  2. {
  3. if (!navigationAction.targetFrame.isMainFrame) {
  4. [webView evaluateJavaScript:@"var a = document.getElementsByTagName('a');for(var i=0;i<a.length;i++){a[i].setAttribute('target','');}" completionHandler:nil];
  5. }
  6. decisionHandler(WKNavigationActionPolicyAllow);
  7. }

在这里,将网页上所有的_blank标签都去掉了。一劳永逸。。。。。。


原文:https://www.jianshu.com/p/3a75d7348843

版权声明:本站文章除特别声明外,均采用署名-非商业性使用-禁止演绎 4.0 国际 许可协议,如需转载,请注明出处