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

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