在开发iOS应用中,经常会需要用到原生与web之间JS的交互,主要有下列3中情况:
1.与UIWebview交互
2.与WKWebview交互
3.利用JavaScriptCore来完成交互
一、在UIWebview中的交互
我们想在oc中修改网页中的代码,这种技术称为JS注入,可以利用webview中的代理方法
// 网页加载完成后会调用
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSMutableString *string = [NSMutableString string];
// 移除头部导航
[string appendString:@"var header = document.getElementsByTagName('header')[0];header.parentElement.removeChild(header);"];
// 移除底部导航
[string appendString:@"var footer = document.getElementsByClassName('footer')[0];footer.parentNode.removeChild(footer);"];
// 移除底部按钮
[string appendString:@"var footBtn = document.getElementsByClassName('footer-btn-fix')[0];footBtn.parentNode.removeChild(footBtn);"];
// 轮播图增加点击事件
[string appendString:@"var image = document.getElementsByClassName('swipe-wrap')[0];image.onclick = function () {window.location.href='tz:newTab'}"];
// 执行js代码
[webView stringByEvaluatingJavaScriptFromString:string];
}
如果想在网页中调用原生的方法,也可以在webview中的代理方法中实现
// 网页将要加载的时候调用
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
// 请求的地址
NSString *url = request.URL.absoluteString;
NSLog(@"url--->%@",url);
// 判断url是否是我们在webViewDidFinishLoad中给轮播图增加的自定义方法
// 如果是,在判断中增加自己的跳转操作
if ([url isEqualToString:@"tz:newTab"]) {
NSLog(@"跳转到新tab页面");
NewTabVC *newTabvc = [[NewTabVC alloc] init];
[self.navigationController pushViewController:newTabvc animated:YES];
}
return YES;
}
二、在WKWebview中的交互
WKWebview是iOS8以后用来替代UIWebview的组件,在内存占用方面有很大的优化,使用时需要导入
#import <WebKit/WebKit.h>
WKWebview的JS注入与UIWebview类似,需要用到navigationDelegate
中的方法
// 网页已经加载完的时候调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
NSMutableString *string = [NSMutableString string];
// 移除头部导航
[string appendString:@"var header = document.getElementsByTagName('header')[0];header.parentElement.removeChild(header);"];
// 移除底部导航
[string appendString:@"var footer = document.getElementsByClassName('footer')[0];footer.parentNode.removeChild(footer);"];
// 移除底部按钮
[string appendString:@"var footBtn = document.getElementsByClassName('footer-btn-fix')[0];footBtn.parentNode.removeChild(footBtn);"];
// 轮播图增加点击事件
[string appendString:@"var image = document.getElementsByClassName('swipe-wrap')[0];image.onclick = function () {window.location.href='tz:newTab'}"];
// 执行JS代码
[webView evaluateJavaScript:string completionHandler:nil];
}
网页中调用原生的方法也与UIWebview类似
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSString *url = navigationAction.request.URL.absoluteString;
if ([url isEqualToString:@"tz:newTab"]) {
NSLog(@"跳转到新tab页面");
NewTabVC *newTabvc = [[NewTabVC alloc] init];
[self.navigationController pushViewController:newTabvc animated:YES];
}
// 回调必须调用,不可省略
decisionHandler(WKNavigationActionPolicyAllow);
}
三、利用JavaScriptCore完成交互
JavaScriptCore是苹果在iOS7后推出的,使用时需要导入框架
在文件头部也需要导入
#import <JavaScriptCore/JavaScriptCore.h>
JS注入
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSMutableString *string = [NSMutableString string];
// 移除头部导航
[string appendString:@"var header = document.getElementsByTagName('header')[0];header.parentElement.removeChild(header);"];
// 移除底部导航
[string appendString:@"var footer = document.getElementsByClassName('footer')[0];footer.parentNode.removeChild(footer);"];
// 移除底部按钮
[string appendString:@"var footBtn = document.getElementsByClassName('footer-btn-fix')[0];footBtn.parentNode.removeChild(footBtn);"];
// 轮播图增加点击事件
[string appendString:@"var image = document.getElementsByClassName('swipe-wrap')[0];image.onclick = function () {pushNewTab()}"];
// 执行js代码
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
[context evaluateScript:string];
}
JS调用原生代码
// 执行js代码
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"pushNewTab"] = ^() {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",[NSThread currentThread]);
NewTabVC *newTabvc = [[NewTabVC alloc] init];
[self.navigationController pushViewController:newTabvc animated:YES];
});
};
github传送门:https://github.com/slkk/OCWebview
网友评论