OC与js交互一(UIWebView与js交互)

效果
html内容
<html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>html文本</title>
            <style>
                .btn{height:40px; width:60%; padding: 0px 30px; background-color: #0071E7; border: solid 1px #0071E7; border-radius:5px; font-size: 1.2em; color: white}
                </style>
            <script>
                //提供给OC调用JS的方法列表
                function alertMessage(msg) {
                    alert('OC调用JS ' + msg )
                }
                function getShareUrl() {
                    return "js中传递出来的分享内容";
                }
                //OC定义的方法供JS调用
                function testMethod() {
                    
                }
                function testMethod1() {
                    //传递的信息
                    var jsonStr = '{"title":"将传给OC的内容", "content":"我是传递的数据"}';
                    getMessage(jsonStr);
                }
                function getMessage(json){
                    //空方法
                }
                </script>
        </head>
        <body>
            <br/><br/>
            <div>
                <label>html文本信息</label>
            </div>
            <br/><br/>

            <div>
                <button class="btn" type="button" onclick="testMethod1()">js调用OC并传递内容</button>
            </div>
            <br/><br/>
            <div>
                <button class="btn" type="button" onclick="testMethod()">js调用OC</button>
            </div>
        </body>
    </html>
OC主要代码
    #import "LFUIWebViewController.h"
    #import <JavaScriptCore/JavaScriptCore.h>

    @interface LFUIWebViewController ()<UIWebViewDelegate>
    @property (strong, nonatomic) UIWebView *webView;
    @end

    @implementation LFUIWebViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self configWebView];
        
        UIButton *rightBtn1 = [UIButton buttonWithType:UIButtonTypeCustom];
        [rightBtn1 setTitle:@"传参给js展示" forState:UIControlStateNormal];
        [rightBtn1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        rightBtn1.frame = CGRectMake(0, 0, 80, 30);
        [rightBtn1 addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
        
        UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [rightBtn setTitle:@"获取js内容" forState:UIControlStateNormal];
        [rightBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        rightBtn.frame = CGRectMake(0, 0, 80, 30);
        [rightBtn addTarget:self action:@selector(clickRightBtn) forControlEvents:UIControlEventTouchUpInside];
        
        self.navigationItem.rightBarButtonItems = @[[[UIBarButtonItem alloc] initWithCustomView:rightBtn],[[UIBarButtonItem alloc] initWithCustomView:rightBtn1]];
    }
    - (void )clickRightBtn{
        // 还可以直接调用js定义的方法
        // 比如getShareUrl()为js端定义好的方法,返回值为分享的内容
        // 我们就可以通过调用这个方法在returnStr中拿到js返回的分享内容
        NSString *returnStr = [self.webView stringByEvaluatingJavaScriptFromString:@"getShareUrl()"];
        NSLog(@"%@",returnStr);
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:returnStr delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
        [alert show];
    }
    - (void )clickBtn{
        [self.webView stringByEvaluatingJavaScriptFromString:@"alertMessage('+OC传递的内容')"];
    }

    - (void )configWebView{
        self.webView = [[UIWebView alloc] initWithFrame:self.view.frame];
        self.webView.delegate = self;
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
        NSURL *baseURL = [[NSBundle mainBundle] bundleURL];
        [self.webView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];
        // 如果不想要webView 的回弹效果
        self.webView.scrollView.bounces = NO;
        // UIWebView 滚动的比较慢,这里设置为正常速度
        self.webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
        [self.view addSubview:self.webView];
    }

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        
        return YES;
    }
    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
        //获取页面title:
        NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
        NSLog(@"webViewTitle --- %@",title);
        
        
        //获取js上下文
        JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        //js中调用 testMethod 方法 通过block调用OC的方法
        context[@"testMethod"] = ^() {
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:@"js调用OC方法" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
                [alert show];
            });
        };
        
        
        context[@"getMessage"] = ^() {
            NSArray *arguments = [JSContext currentArguments];
            NSString *content = @"";
            for (JSValue *jsValue in arguments) {
                NSLog(@"=======%@",jsValue);
                content = [NSString stringWithFormat:@"%@%@",content,jsValue];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"js传递出来的内容" message:content delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
                [alert show];
            });
        };
        
    }



    @end
简单说明下每个地方的意思

1.1.OC调用js

OC与js交互,需要和web端协商好交互的方法。


譬如上面这段代码,OC调用js,从html中获取分享的内容,在html中声明一个方法,将分享的内容,直接以字符串的形式return出来。

function getShareUrl() {
            return "js中传递出来的分享内容";
        }

OC通过 stringByEvaluatingJavaScriptFromString 这个方法我们可以在iOS中与UIWebView中的网页元素交互,需要注意的是这个方法需要放在UIWebView中的页面加载完成之后去调用

// 还可以直接调用js定义的方法
// 比如getShareUrl()为js端定义好的方法,返回值为分享的内容
// 我们就可以通过调用这个方法在returnStr中拿到js返回的分享内容
NSString *returnStr = [self.webView stringByEvaluatingJavaScriptFromString:@"getShareUrl()"];
NSLog(@"%@",returnStr);

有些时候,我们需要通过OC调用js的方法,并传递参数给html进行处理。譬如下面这个用例,OC调用js的弹框,并传递需要展示的内容,我们在html中定一个方法,供OC调用

function alertMessage(msg) {
            alert('OC调用JS ' + msg )
        }

OC可以通过

[self.webView stringByEvaluatingJavaScriptFromString:@"alertMessage('+OC传递的内容')"];

直接将内容传递给html展示。

有时候我们单纯的想获取html中的一些标签内容,也可以通过stringByEvaluatingJavaScriptFromString 这个方法去获取

//获取页面title:
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
NSLog(@"webViewTitle --- %@",title);

还可以获取其他的一些内容

    document:属性
    document.title                 //设置文档标题等价于HTML的<title>标签
    document.bgColor               //设置页面背景色
    document.fgColor               //设置前景色(文本颜色)
    document.linkColor             //未点击过的链接颜色
    document.alinkColor            //激活链接(焦点在此链接上)的颜色
    document.vlinkColor            //已点击过的链接颜色
    document.URL                   //设置URL属性从而在同一窗口打开另一网页
    document.fileCreatedDate       //文件建立日期,只读属性
    document.fileModifiedDate      //文件修改日期,只读属性
    document.fileSize              //文件大小,只读属性
    document.cookie                //设置和读出cookie
    document.charset               //设置字符集 简体中文:gb2312
    document:方法
    document.write()                      //动态向页面写入内容
    document_createElement_x_x(Tag)           //创建一个html标签对象
    document.getElementByIdx_x_x(ID)           //获得指定ID值的对象
    document.getElementsByName(Name)      //获得指定Name值的对象
    document.body.a(oTag)
    body:子对象
    document.body                   //指定文档主体的开始和结束等价于<body></body>
    document.body.bgColor           //设置或获取对象后面的背景颜色
    document.body.link              //未点击过的链接颜色
    document.body.alink             //激活链接(焦点在此链接上)的颜色
    document.body.vlink             //已点击过的链接颜色
    document.body.text              //文本色
    document.body.innerText         //设置<body>...</body>之间的文本
    document.body.innerHTML         //设置<body>...</body>之间的HTML代码
    document.body.topMargin         //页面上边距
    document.body.leftMargin        //页面左边距
    document.body.rightMargin       //页面右边距
    document.body.bottomMargin      //页面下边距
    document.body.background        //背景图片
    document.body.a(oTag) //动态生成一个HTML对象
    location:子对象
    document.location.hash          // #号后的部分
    document.location.host          // 域名+端口号
    document.location.hostname      // 域名
    document.location.href          // 完整URL
    document.location.pathname      // 目录部分
    document.location.port          // 端口号
    document.location.protocol      // 网络协议(http:)
    document.location.search        // ?号后的部分
    常用对象事件:
    documeny.location.reload()          //刷新网页
    document.location.reload(URL)       //打开新的网页
    document.location.assign(URL)       //打开新的网页
    document.location.replace(URL)      //打开新的网页
    selection-选区子对象
    document.selection

参考链接1
参考链接2

1.2.js调用OC


我们在js中创建两个按钮,定义两个方法

      function testMethod() {
            
        }
        function testMethod1() {
            //传递的信息
            var jsonStr = '{"title":"将传给OC的内容", "content":"我是传递的数据"}';
            getMessage(jsonStr);
        }
        function getMessage(json){
            //空方法
        }

在OC中我们做下面的一些操作(需要倒入#import <JavaScriptCore/JavaScriptCore.h>这个头文件)
我们在 - (void)webViewDidFinishLoad:(UIWebView *)webView 这个方法中,首先获取js运行的上下文

//获取js上下文
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

通过这个上下文利用block调用OC的方法

 //js中调用 testMethod 方法 通过block调用OC的方法
context[@"testMethod"] = ^() {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:@"js调用OC方法" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
        [alert show];
    });
};


context[@"getMessage"] = ^() {
    NSArray *arguments = [JSContext currentArguments];
    NSString *content = @"";
    for (JSValue *jsValue in arguments) {
        NSLog(@"=======%@",jsValue);
        content = [NSString stringWithFormat:@"%@%@",content,jsValue];
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"js传递出来的内容" message:content delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
        [alert show];
    });
};

需要注意的是js调用OC需要在主线程中操作

dispatch_async(dispatch_get_main_queue(), ^{

        });

参考链接3
<JavaScriptCore/JavaScriptCore.h>这个头文件里面一些类较全的说明
Demo集合

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章