OC与js交互一(UIWebView与js交互)
2018-11-15 本文已影响0人
重驹
效果

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.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集合