效果
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集合