前言
下午運(yùn)營(yíng)的同事在A(yíng)PP的跑馬燈上配了一個(gè)淘寶的鏈接,效果如下圖:
但點(diǎn)擊頁(yè)面上的商品,頁(yè)面沒(méi)反應(yīng),打印出來(lái)跳轉(zhuǎn)的鏈接是這樣:
https://uland.taobao.com/coupon/edetail?spm=a3126.7792474/a.1005.1&e=cXimz4TLjIQGQASttHIRqWKQY7MjCdZaX1Ntma1L86+EdvD4wwM+Y73pFa9Azc+ZXBymrrjpoBQ6fLdAZDu8i42sTXYoCSgGDfqEFBOhTczH84UUJ6ek81fdFfqCDAtNSy49IabX1vktw6/aQUEtrNCtedbC7d6D&mt=1&ptl=bucket:_TL-43223;prepvid:a3126.7792474/a_1530101783882_3161184732177076;engpvid:100_10.103.67.73_12253_9391530101784658599;from:temaisearch
檢查了一下鏈接也沒(méi)發(fā)現(xiàn)有什么問(wèn)題,為什么就不能跳轉(zhuǎn)頁(yè)面呢?然后將這個(gè)鏈接寫(xiě)死為 webview頁(yè)面的 url,這時(shí)頁(yè)面可以正常跳轉(zhuǎn)了.為什么相同的一個(gè)鏈接會(huì)因?yàn)椴僮鞯姆绞讲挥?而表現(xiàn)為兩種結(jié)果?
問(wèn)題出現(xiàn)的原因
在電腦瀏覽器上查看了那個(gè)淘寶頁(yè)面的html 元素后,發(fā)現(xiàn)
超鏈接a標(biāo)簽的target屬性為_(kāi)blank
理解 HTML < a>標(biāo)簽的target屬性
_blank -- 在新窗口中打開(kāi)鏈接
_parent -- 在父窗體中打開(kāi)鏈接
_self -- 在當(dāng)前窗體打開(kāi)鏈接,此為默認(rèn)值
_top -- 在當(dāng)前窗體打開(kāi)鏈接横缔,并替換當(dāng)前的整個(gè)窗體(框架頁(yè))
根據(jù)上面的說(shuō)明當(dāng)target屬性值為_(kāi)blank昆汹,是讓瀏覽器新開(kāi)一個(gè)頁(yè)面來(lái)打開(kāi)鏈接艰管,而不是在原網(wǎng)頁(yè)上打開(kāi)匕争。
在UIWebView上履植,只有一個(gè)頁(yè)面妒御,所以會(huì)自動(dòng)在原來(lái)的頁(yè)面上打開(kāi)新鏈接。
但是在WKWebView上就不是這樣了。
用戶(hù)點(diǎn)擊網(wǎng)頁(yè)上的鏈接愿卸,需要打開(kāi)新頁(yè)面時(shí),會(huì)先調(diào)用WKWebView 的 WKNavigationDelegate
代理方法:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
這個(gè)方法的參數(shù) WKNavigationAction 中有兩個(gè)屬性:sourceFrame和targetFrame截型,分別代表這個(gè)action的出處和目標(biāo)擦酌。類(lèi)型是 WKFrameInfo 。WKFrameInfo有一個(gè) mainFrame 的屬性菠劝,正是這個(gè)屬性標(biāo)記著這個(gè)frame是在主frame里還是新開(kāi)一個(gè)frame赊舶。
如果 targetFrame 的 mainFrame 屬性為NO,表明這個(gè) WKNavigationAction 將會(huì)新開(kāi)一個(gè)頁(yè)面赶诊。
WKWebView遇到這種情況笼平,將會(huì)調(diào)用 它的 WKUIDelegate 代理方法:
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
如果實(shí)現(xiàn)這個(gè)方法,會(huì)返回一個(gè)新的WKWebView舔痪,讓 WKNavigationAction 在新的webView中打開(kāi)寓调。如果你沒(méi)有設(shè)置 WKUIDelegate代理和沒(méi)有實(shí)現(xiàn)這個(gè)代理方法。那么WKWebView將什么事情都不會(huì)做锄码,也就是你點(diǎn)那個(gè)按鈕沒(méi)反應(yīng)夺英。
解決辦法
解決辦法1:
直接在原有的decidePolicyForNavigationAction代理方法中加上以下代碼:
if (navigationAction.targetFrame == nil) {
[webView loadRequest:navigationAction.request];
}
//如果方法中已有這行代碼,則不需要再加了,否則運(yùn)行會(huì)報(bào)錯(cuò)
decisionHandler(WKNavigationActionPolicyAllow);
解決辦法2:
在代碼中實(shí)現(xiàn)以下代理方法:
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
//假如是重新打開(kāi)窗口的話(huà)
if (!navigationAction.targetFrame.isMainFrame) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
解決辦法3:
將網(wǎng)頁(yè)上所有a標(biāo)簽的target屬性值都去掉
- (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','_self');}" completionHandler:nil];
}
decisionHandler(WKNavigationActionPolicyAllow);
}
不過(guò)用這種方式點(diǎn)擊兩次才能跳轉(zhuǎn)撩独,因?yàn)榈谝淮吸c(diǎn)擊時(shí)呐能,會(huì)先用JavaScript腳本把< a >標(biāo)簽target屬性原來(lái)的_blank替換為_(kāi)self,但這時(shí)的navigationAction.targetFrame為nil,因此不會(huì)跳轉(zhuǎn)頁(yè)面。
第二次點(diǎn)擊時(shí)拢锹,navigationAction.targetFrame.isMainFrame的值才為NO施绎,所以這時(shí)才能跳轉(zhuǎn)頁(yè)面妒穴。