UIWebView---UIWebView和JavaScript交互

来源:互联网 发布:淘宝详情页图片模板 编辑:程序博客网 时间:2024/05/02 05:06

今天来学一下JS和iOS交互的

下面举个例子

要做出这样的效果



html页面代码

<!DOCTYPE html><html>    <body>        <h1 id="id1">I'm Html </h1>        <button type="button" onclick=clickMe()> Talk To iOS</button>        <script><!--            第一种调用方式-->            function clickMe() {                window.location.href = "Gap:I'm iOS, copy that";            }        </script>    </body></html>


从Html发消息到iOS端

先说说html5上的按钮点击
window.location.href = "Gap:I'm iOS, copy that";
这样会产生一次请求, 我们就可以截取到链接

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{    NSString *path=[[request URL] absoluteString];    NSLog(@"%@",path);    if ([path rangeOfString:@"gap:"].location != NSNotFound) {        NSString *str = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];        self.iosLabel.text = [str stringByReplacingOccurrencesOfString:@"gap:" withString:@""];        return NO;    }    return YES;}


从ios端发送到Html

插一段js代码来改变id为“id1”的元素的文字修改掉
- (IBAction)talkToHtmlAction:(id)sender{    NSString *js = @"var label = document.getElementById('id1'); label.innerText= 'I receive Your Message'";    // NSString *js = @"document.getElementById('id1').innerText='I receive Your Message'";    [self.webView stringByEvaluatingJavaScriptFromString:js];}

如果事情真的这么简单就好了

下面来说一些比较复杂的

UIWebView发起特殊请求的方式

<!DOCTYPE html><html>    <body>        <h1 id="id1">I'm Html </h1>        <button type="button" onclick=clickMe()> Talk To iOS</button>        <script><!--            第一种调用方式-->            function clickMe() {               <span style="color:#ff0000;"> window.location.href = "Gap:I'm iOS, copy that";</span>            }        </script>    </body></html>
这里是通过修改window.location.href(也可以用document.location)来发起一个特殊请求

但是如果你需要2次修改window.location.href那会怎么样呢 ?只有后面的那句才有用

function clickMe() {                window.location.href = "http://www.w3school.com.cn";                window.location.href = "Gap:I'm iOS, copy that";            }
那我们该怎么办呢

把clickme()的函数里面的换掉 (参数要用UTF8编码一下)

 function clickMe() {                // 简单传值                // var text = "I'm iOS, copy that";                                // 传个json字符串过去                var text = '{"length1":76,"length2":155,"length3":76,"length4":155,"length5":76}';                var url = "gap:" + EncodeUtf8(text);                                // 顺序很重要                loadURL(url);                //window.location.href = "http://www.w3school.com.cn";            }         function loadURL(url) {               window.location.href=url;                var iFrame;                iFrame = document.createElement("iframe");                  iFrame.setAttribute("src", url);                 iFrame.setAttribute("style", "display:black;");                  iFrame.setAttribute("height", "100px");                  iFrame.setAttribute("width", "100px");                  iFrame.setAttribute("frameborder", "10");                  document.body.appendChild(iFrame);                  // 发起请求后这个iFrame就没用了,所以把它从dom上移除掉                   iFrame.parentNode.removeChild(iFrame);                    iFrame = null;           }

 function EncodeUtf8(s1)        {            // escape函数用于对除英文字母外的字符进行编码。如“Visit W3School!”->"Visit%20W3School%21"            var s = escape(s1);            var sa = s.split("%");//sa[1]=u6211            var retV ="";            if(sa[0] != "")            {                retV = sa[0];            }            for(var i = 1; i < sa.length; i ++)            {                if(sa[i].substring(0,1) == "u")                {                    retV += Hex2Utf8(Str2Hex(sa[i].substring(1,5)));                    if(sa[i].length>=6)                    {                        retV += sa[i].substring(5);                    }                }                else retV += "%" + sa[i];            }            return retV;        }



这样子的话既可以web跳界面又可以顺利的和ios交互

如果我想传递一些复杂一点的参数呢

可以直接传个json字符串过去

 var text = '{"length1":76,"length2":155,"length3":76,"length4":155,"length5":76}'; var url = "gap:" + EncodeUtf8(text); loadURL(url);

接收参数的协议里面也要改

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{    NSString *path=[[request URL] absoluteString];    NSLog(@"%@",path);    if ([path rangeOfString:@"gap:"].location != NSNotFound) {        NSString *str = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];        NSString *strDic = [str stringByReplacingOccurrencesOfString:@"gap:" withString:@""];        NSData *data = [strDic dataUsingEncoding:NSUTF8StringEncoding];        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];        NSLog(@"dic:%@", dic);        self.iosLabel.text = [str stringByReplacingOccurrencesOfString:@"gap:" withString:@""];        return NO;    }    return YES;}


常见的JS调用

(1)获取标题

NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];

(2)获取URL

NSString *url = [webview stringByEvaluatingJavaScriptFromString:@"document.location.href"];

一些注意事项

《参考自ios进阶开发》

同步和异步

UIWebView调用原生界面时是异步操作

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;


原生界面调用UIWebView是同步 

[self.webView stringByEvaluatingJavaScriptFromString:js];//直接返回NSString

这一点要注意一下

线程阻塞

当oc调用stringByEvaluatingJavaScriptFromString时 可能是由于js是单线程的原因会阻塞js代码的执行

解决办法是js端用defer把iFrame的插入延后执行

主线程问题

由于stringByEvaluatingJavaScriptFromString必须在主线程执行,所以如果主线程执行时间过长就会阻塞UI的更新 我们应该尽量让js的代码执行时间短

第三方库

(1)WebViewJavascriptBridge
https://github.com/marcuswestin/WebViewJavascriptBridge
(2)cordova
http://cordova.apache.org/

0 0
原创粉丝点击