美文网首页
iOS 中的JS交互

iOS 中的JS交互

作者: MeteorCode | 来源:发表于2018-03-07 16:01 被阅读33次

在iOS的webview开发中,都会用到和HTML交互。一般JS的交互一般有几种:

  • OC调用JS
  • JS调用OC
  • 动态给HTML标签添加时间

JS给OC传参

有两种方式:
1- 通过URL传值
2- 通过自带的库 JavaScriptCore 实现;

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf8">
            <script language="javascript">

            function buttonClick() {
                loadURL("haleyAction://buttonClick?title=按钮标题&content=内容&url=http://www.baidu.com");
            }
            
            function clickResult(id, text,url) {
                var content = id+","+text+","+url;
                asyncAlert(content);
                document.getElementById("returnValue").value = content;
            }
            
            </script>
            </head>
    
    <body>
        <h1>这是按钮调用</h1>
        <input type="button" value="点击" onclick="buttonClick()" />
    </body>
</html>
  • 通过URL传值
//UIWebViewDelegate
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    //网页的url
    NSString *requestStr = [[request.URL absoluteString] stringByRemovingPercentEncoding];

    //判断url中存在自定义协议头 "objc://"
    if ([requestStr hasPrefix:@"objc://"]) {

        // 通过"://"为中心将url分割成两部分,放进数组arr
        NSArray *arr = [requestStr componentsSeparatedByString:@"://"];
        //参数字符串
        NSString *paramStr = arr[1];

        //通过与HTML约定好的字符"_",取得参数的数组
        NSArray *arr2 = [paramStr componentsSeparatedByString:@"_"];

        if (arr2.count) {

        } else {
            NSLog(@"无参数");
        }
        return NO;
    }
    return YES;
}
  • 通过系统库 JavaScriptCore 实现;
    在项目中拖入系统库 JavaScriptCore.framework,遵守UIWebViewDelegate协议;
    当HTML代码:
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf8">
            <script language="javascript">

            function buttonClick() {
                clickHandle('测试分享的标题','测试分享的内容','url=http://www.baidu.com');
            }
            
            function clickResult(id,text,url) {
                var content = id+","+text+","+url;
                asyncAlert(content);
                document.getElementById("returnValue").value = content;
            }

            </script>
            </head>
    
    <body>
        <h1>这是按钮调用</h1>
        <input type="button" value="按钮点击" onclick="buttonClick()" 
    </body>
</html>

// UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {

    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    context[@"buttonClick"] = ^{

        NSArray *array = [JSContext currentArguments];
        for (id obj in array) { 
        }
    };

    context[@"clickHandle"] = ^() {
        NSArray *array = [JSContext currentArguments]; //获取html中 clickHandle 方法中的参数,JS传给OC的参数
        
        if (array.count < 3) {
            return ;
        }
        
        NSString *title = [array[0] toString];
        NSString *content = [array[1] toString];
        NSString *url = [array[2] toString];
        
        // 将分享结果返回给js
        NSString *jsStr = [NSString stringWithFormat:@"clickResult('%@','%@','%@')",title,content,url];
        [[JSContext currentContext] evaluateScript:jsStr];
    };
}

OC给JS传参

  • 通过 stringByEvaluatingJavaScriptFromString 方法
    NSString *jsStr = [NSString stringWithFormat:@"clickResult('%@','%@','%@')",title,content,url];
    [self.webView stringByEvaluatingJavaScriptFromString:jsStr];

其中clickResult是JS方法名;

  • 通过 JavaScriptCore 框架实现;
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
  NSString *jsStr = [NSString stringWithFormat:@"clickResult('%@','%@','%@')",title,content,url];
[context evaluateScript: jsStr];

动态写入JS点击事件

#pragma mark - webViewDelegate
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    if([request.URL.scheme isEqualToString:@"image-preview"]){

        //触发点击事件  -- >拿到是第几个标签被点击了
        NSString *clickImg = request.URL.resourceSpecifier;

        //遍历数组,查询查找当前第几个图被点击了
        NSInteger selectIndex = 0;
        for(int i = 0; i< self.imgsArr.count;i++){
            NSString *imgUrl = self.imgsArr[i];
            if ([imgUrl isEqualToString:clickImg]) {
                selectIndex = i;
                break;
            }
        }
        //拿到当前选中的index  -- > 使用图片浏览器让图片显示出来
        return NO;
    }
    return YES;
}

-(void)webViewDidFinishLoad:(UIWebView *)webView {

    //加载完成之后开始注入js事件 - 写入的是JS代码
    [self.webView stringByEvaluatingJavaScriptFromString:@"\
     function buttonClick(){\
        var imgs=document.getElementsByTagName('img');\
        var length=imgs.length;\
        for(var i=0;i<length;i++){\
            img=imgs[i];\
            img.onclick=function(){\
                window.location ='image-preview:'+this.src;\
            }\
        }\
     }\
     "];

    //触发方法 给所有的图片添加onClick方法
    [self.webView stringByEvaluatingJavaScriptFromString:@"buttonClick();"];
    
    //拿到最终的html代码
//    NSString *HTMLSource = [self.webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('script')[0].innerHTML"];
    //调用html代码
    [self.webView stringByEvaluatingJavaScriptFromString:@"sendMsg('我是objc传入的值');"];

    //拿到所有img标签对应的图片
    [self imageHandle];
}

-(void) imageHandle {
    //要拿到所有img标签对应的图片的src
    //1.拿到img标签的个数
    NSUInteger length = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('img').length"] integerValue];
    //2.遍历标签,拿到标签中src的内容
    for (int i =0 ; i < length; i++) {
        NSString *jsStr = [NSString stringWithFormat:@"document.getElementsByTagName('img')[%zi].src",i];
        NSString *img = [self.webView stringByEvaluatingJavaScriptFromString:jsStr];
        //3.将标签中src内容存入数组
        [self.imgsArr addObject:img];
    }
}

通过第三方库实现JS和OC之前的传值 - WebViewJavascriptBridge

以后写!

相关文章

网友评论

      本文标题:iOS 中的JS交互

      本文链接:https://www.haomeiwen.com/subject/ledrxftx.html