【iOS开发之OC和JS互调】
1.OC中调用JS代码
- 公司的移动端需要加载一个现有的网页,并且要在原网页要做一些小的调整,如将网页的标题改一下加载到手机的app上,此时就可以在app的oc代码中加入JS代码来实现。如下例子,我要加载一个鲜花网(http://www.xianhua.cn/m/)并把它原有的标题"手机鲜花网"改为"鲜花网".
- 原网页如下
- 代码如下,先在viewDidLoad中加载网页,并加上菊花,隐藏网页(因为直接加载处理的标题不是我们想要的),再到 webViewDidFinishLoad: 这个方法中将js代码写入到一个字符串,作为参数传入这个方法 stringByEvaluatingJavaScriptFromString: ,此时网页就被改了,最后停止菊花,显示网页。
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 //加载HTML 5 NSURL *url = [NSURL URLWithString:@"http://www.xianhua.cn/m/"]; 6 NSURLRequest *request = [NSURLRequest requestWithURL:url]; 7 [self.webView loadRequest:request]; 8 9 // 先将网页隐藏 10 self.webView.scrollView.hidden = YES; 11 self.webView.backgroundColor = [UIColor grayColor]; 12 13 // // 加菊花 14 UIActivityIndicatorView *displayView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 15 self.displayView = displayView; 16 // 开始转圈 17 [displayView startAnimating]; 18 displayView.center = self.view.center; 19 [self.webView addSubview:displayView]; 20 } 21 22 23 #pragma - 代理方法 24 -(void)webViewDidFinishLoad:(UIWebView *)webView{ 25 NSString *str = @"document.getElementById('header').getElementsByTagName('h1')[0].innerText = '鲜花网';""document.getElementsByClassName('detail_btns2')[0].remove();""document.getElementById('xiazaiapp').getElementsByTagName('a')[0].innerText = '下载大神6期鲜花网(www.6q.com)App';"; 26 // 加载js代码 27 [webView stringByEvaluatingJavaScriptFromString:str]; 28 29 // 当执行完以上js代码后,就停止动画,并显示网页 30 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 31 [self.displayView stopAnimating]; 32 self.webView.scrollView.hidden = NO; 33 }); 34 }
- 结果如下,可以看到标题已经改成鲜花网了:
2. JS中调用OC方法
- 在网页中点击一个按钮打开手机相册,这样的需求就需要在js代码中调用oc的方法
- 可以先在js中布局一个按钮,并写一个函数,当点击按钮时就调用这个函数,函数中一定要传递一个参数,这个参数就包括:协议头(用来识别是谁发送的请求)和方法名,如下代码,协议头是"js:///",要调用的方法名是"openCamera":
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title>打开相册</title> 6 <style> 7 body{ 8 padding: 30px; 9 } 10 </style> 11 </head> 12 <body> 13 <button onclick="openCamera();">打开相册</button> 14 <script type="text/javascript"> 15 // 内置对象 window 16 function openCamera(){ 17 window.location.href = 'js:///openCamera'; 18 } 19 </script> 20 </body> 21 </html>
- 此时JS代码已经完成,再到OC中解析,在这个方法中webView:shouldStartLoadWithRequest:navigationType:获取JS传递过来的参数,并解析它,将方法名截取出来,调用该方法
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 NSURL *url = [[NSBundle mainBundle] URLForResource:@"openCamera" withExtension:@"html"]; 4 NSURLRequest *request = [NSURLRequest requestWithURL:url]; 5 [self.webView loadRequest:request]; 6 } 7 8 9 // 打开相册 10 - (void)openCamera{ 11 UIImagePickerController *vc = [[UIImagePickerController alloc] init]; 12 vc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 13 [self presentViewController:vc animated:YES completion:nil]; 14 } 15 16 17 #pragma mark -<UIWebViewDelegate> 18 19 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 20 NSString *webUrl = request.URL.absoluteString; 21 NSRange range = [webUrl rangeOfString:@"js:///"]; 22 // 获取协议头的第一个字母位置 23 NSUInteger location = range.location; 24 25 // 如果协议正确 26 if (location != NSNotFound) { 27 // 从协议头最后一个字母开始,全部转为字符串(拿到方法名) 28 NSString *str = [webUrl substringFromIndex:location + range.length]; 29 // 将字符串转为selector,并给self调用 30 SEL open = NSSelectorFromString(str); 31 [self performSelector:open]; 32 } 33 return YES; 34 }