[IOS Objective-c] 解決UIWebView target = '_blank' 不能彈出

現在是HTML5大時代了,相信不少人在用H5做手機項目。
現今Apple的審批非常之鬆,已經和以往拒絕純WebVIew項目的態度不同了。
現在開發者在Xcode上只需放一個WEBVIEW,放入URL,就可以上架了,若你的網頁足夠Responive.

我想,大慨是WKWebview崛起的緣故吧。
不過Wkwebview有一個硬傷,就是Cookies管理。不過這不是今天的議題。

話歸正傳,我想不少人試過在webview的html網頁中,點擊超連結a tag, 若屬性是 target='_blank', 在html中 target='_blank' 會令瀏覽器popup 一個新視窗。但是,這個屬性在ios上并不生效,這意味著要自己作管理。

看到這個問題時,在StackOverflow上看見一些解決方案,但并不切合我的需求:

  1. 不使用A tag, 用javascript中windows.open 實現popup。這個方案可行。但若果HTML那邊的管理權限不是由IOS開發者所屬呢?你總不能要求Google或百度幫你加入windows.open這段代碼吧?

  2. 在 UIWebView的 Delegate [webViewDidFinishLoad]中爬一次整個Document的所有代碼,發現target='_blank'時,注入windows.open代碼。 這個也是可行的,但webViewDidFinishLoad只在WebView準備好時執行一次,若我要轉跳幾個URL呢?

後來我查閱了一下Apple官方文檔的Delegate方法,發現了「shouldStartLoadWithRequest」這個callback, 這個callback是在每一條request發出前會執行前都會Trigger的,好了,這不就完成了嗎?

代碼如下:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *fullRequest = request.URL.absoluteString;
    NSString *scriptString = [NSString stringWithFormat:@"%@%@%@", @"document.querySelectorAll(\"[href='", fullRequest, @"']\")[0].getAttribute('target');"];
    NSString *result = [webView stringByEvaluatingJavaScriptFromString:scriptString];
    
    if ( [result isEqualToString:@"_blank"]){
        [[UIApplication sharedApplication] openURL:request.URL];
        return false;
    }
    return true;
}

以上思路簡單并且清晰,在每個request之前,都利用stringByEvaluatingJavaScriptFromString:scriptString 捉出該request所在的a tag中"target" 的 attribute, 若為blank, 則用 [[UIApplication sharedApplication] openURL:request.URL]; 來彈出瀏覽器。這個方法能兼容跳頁情況發生。

新年快樂,謝謝觀看。

你可能感兴趣的:([IOS Objective-c] 解決UIWebView target = '_blank' 不能彈出)