UIWebView和js交互

之前做过一个项目,里面涉及到显示公式之类的东西就必须要在项目里面嵌入网页,最麻烦的就是网页需要在本地自己拼凑成html,然后再使用UIWebView加载出来,这里面就涉及到了一些关于OC和JavaScript交互的问题,对于第一次接触这些的人,还是会走一些弯路。我在此把自己学习的分享出来,希望帮到一些人。

分两部分介绍,第一部分是加载本地网页。然后进行交互。第二部分是加载服务器的网页后进行交互。

一  加载本地网页(demo下载地址}

  加载本地网页的话,由于网页都是自己写,我们可以把需要的请求参数都提前写好。这样在OC代码里面就可以直接的和网页交互。
  OC和js交互的原理是网页发起一个请求,然后WebView截获这个请求,对于这个请求的话可以是很多种的。我的Demo里面也总结了两种不同的方法。

  第一种

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <script type="text/javascript">  
  2. function sendCommand(cmd,param){  
  3.     var url="zjq:"+cmd+":"+param;  
  4.     document.location = url;  
  5. }  
  6. </script>  

第二种

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <script language="javascript">  
  2.            function loadURL(url) {  
  3.                var iFrame;  
  4.                iFrame = document.createElement("iframe");  
  5.                iFrame.setAttribute("src", url);  
  6.                iFrame.setAttribute("style""display:none;");  
  7.                iFrame.setAttribute("height""0px");  
  8.                iFrame.setAttribute("width""0px");  
  9.                iFrame.setAttribute("frameborder""0");  
  10.                document.body.appendChild(iFrame);  
  11.                // 发起请求后这个iFrame就没用了,所以把它从dom上移除掉  
  12.                iFrame.parentNode.removeChild(iFrame);  
  13.                iFrame = null;  
  14.            }  
  15.            function check() {  
  16.                loadURL("zjq:zjqjjqzjq");  
  17.            }  
  18.   </script>  

用的比较多也比较简洁的是第一种,第二种的话是发起一个假的请求,一句话,都是为了网页能够刷新一下,WebView的委托才会被调用,才能够拦截到请求,然后做出相应的处理。

1.在界面里面添加一个一个UIWebView和一个按钮,按钮用于OC对网页发起操作 
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. currentY = self.navigationController.navigationBar.frame.size.height;  
  2.     screen = [UIScreen mainScreen].bounds.size;  
  3.     _webView  = [[UIWebView alloc] initWithFrame:CGRectMake(0, currentY, screen.width, screen.height-100)];  
  4.      
  5.     self.automaticallyAdjustsScrollViewInsets = NO;  
  6.      _webView.delegate = self;  
  7. //    _webView.backgroundColor = [UIColor clearColor];  
  8.     [self.view addSubview:_webView];  
  9.     UIButton * button  = [[UIButton alloc] initWithFrame:CGRectMake(50, screen.height-50, screen.width-10030)];  
  10.     [button addTarget:self action:@selector(appTojs) forControlEvents:UIControlEventTouchUpInside];  
  11.     [button setTitle:@"app向网页发送消息" forState:UIControlStateNormal];  
  12.     [button setBackgroundColor:[UIColor grayColor]];  
  13.     [self.view addSubview:button];  
2.加载html页面
加载页面的方式也很多
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.   NSString * path = [[NSBundle mainBundle] bundlePath];  
  2.     NSURL * baseURL = [NSURL fileURLWithPath:path];  
  3.     NSString * htmlFile = [[NSBundle mainBundle] pathForResource:@"Test" ofType:@"html"];  
  4.     NSString * htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:(NSUTF8StringEncoding) error:nil];  
  5. //    从本地加载一个html文件。  
  6.     [self.webView loadHTMLString:htmlString baseURL:baseURL];  
这种方式把html当作文件加载
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. NSString * htmlPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"index.html"];  
  2.  [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:htmlPath]]];  
这种方法则是相当于发起一个请求
3.实现委托函数(js对oc交互)
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //当网页视图被指示载入内容而得到通知。应当返回YES,这样会进行加载  
  2. - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{  
  3.     NSURL *url = [request URL];  
  4.     if ([[url scheme] isEqualToString:@"zjq"]) {  
  5.         UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"通知" message:[NSString stringWithFormat:@"%@%@",@"发起请求的url是:",[url absoluteString]]delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];  
  6.         [alertView show];  
  7.     }  
  8. //多个  
  9. //    NSString *requestString = [[request URL] absoluteString];//获取请求的绝对路径.  
  10. //    NSArray *components = [requestString componentsSeparatedByString:@":"];//提交请求时候分割参数的分隔符  
  11. //    if ([components count] > 1 && [(NSString *)[components objectAtIndex:0] isEqualToString:@"testapp"]) {  
  12. //        //过滤请求是否是我们需要的.不需要的请求不进入条件  
  13. //        if([(NSString *)[components objectAtIndex:1] isEqualToString:@"alert"])  
  14. //  
  15.   
  16.   
  17.     return YES;  
  18.  }  
这个返回值一定要是YES的,否则加载不出来,对于上面这个委托方法是用来处理js发起的请求,对于请求的判断,也是可以使用两种不同的方法。上面的源码里面都已经给出。个人更喜欢第一种,如果有多种不同的请求,又有很对子请求的话第二种应该好一些。
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //开始请求调用的方法,可以加个指示器  
  2. - (void)webViewDidStartLoad:(UIWebView *)webView{  
  3.      
  4. }  
  5.  //结束请求调用的方法,可以加个指示器  
  6. - (void)webViewDidFinishLoad:(UIWebView *)webView{  
  7.   
  8.   
  9. }  
  10. //加载失败的方法  
  11. - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{  
  12.     NSLog(@"error是%@",error);  
  13. }  
  14. 4.oc对js交互  
  15. oc对html进行修改的话,我们使用一个方法就可以。stringByEvaluatingJavaScriptFromString,苹果也就只给了这一个方法。  
  16. - (void)appTojs{  
  17.     NSString * js = @" var p = document.createElement('p'); p.innerText = '增加一行';document.body.appendChild(p);";  
  18.     [self.webView stringByEvaluatingJavaScriptFromString:js];  
  19. }  

二 加载网络服务器的页面(demo下载地址)

 页面加载本身没有多大的难度,我这里主要介绍的是页面加载结束后,如何把我们的js代码注入到原来的html页面里面,我们才可以知道相应的请求的scheme等的相应信息。否则我的委托函数里面没有判断的根据嘛。
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.  - (void)webViewDidFinishLoad:(UIWebView *)webView{  
  2.   
  3.   
  4.   
  5.   
  6.    NSString * string =  [webView stringByEvaluatingJavaScriptFromString:@"var script = document.createElement('script');"  
  7.      "script.type = 'text/javascript';"  
  8.      "script.text = \"function sendCommand(cmd,param){"  
  9.      "var url='zjq:'+cmd+':'+param;"  
  10.      "document.location = url;"  
  11.      "}"  
  12.      "var btn = document.getElementById('test');"  
  13.      "btn.onclick = function(){"  
  14.        "sendCommand('zjq','jump');"  
  15.      "}\" ;"  
  16.      "alert(script.text);"  
  17.      "document.getElementsByTagName('html')[0].appendChild(script);"];  
  18.     NSLog(@"返回的消息是%@",string);  
  19.   
  20.   
  21.    //答应整个页面可以看到我们得代码是否加进去了  
  22.     NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];  
  23.     NSString *text = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.innerHTML"];  
  24.     NSLog(@"url是,%@,text%@",currentURL,text);  
  25. }  
   这里主要的去区别就是在加载结束后我得把我得js代码注入到原网页中
不的不提醒一下上面的js代码,如果你不是很熟悉的话,修改一些参数就可以,OC里面要不把js弄错还真是困难,那么多引号,少一个都有可能出问题。反正我弄了一个下午。改来改去总是出错。可能和我不太熟悉JS有很大的关系。这个注入之后,其他的个本地加载没多大区别了。不过有些网页是加了限制不让注入的。团队在开发的时候肯定需要协调好。我demo里面是使用了百度。代码是进去了,但是还是运行不了,百度应该是拦截了它。
于是Demo就是现在这个样了,我用了一个本地的页面的,但是和从服务器加载出来的差不多。里面我并没有提前写好请求的地址之类的。 是使用OC给html注入的。

  参考资料地址时间有些久我都不记得了,这里不在列出,谢谢前辈们,加了很多个人理解,总觉得还是有些问题。不足之处请批评指正。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值