首先要理清一下關(guān)系:
HTML:一些網(wǎng)頁控件。
超文本標記語言,標準通用標記語言(SGM或SGML)下的一個應(yīng)用。
“超文本”就是指 頁面內(nèi)可以包含圖片、鏈接,甚至音樂、程序 等非文字元素。
超文本標記語言的結(jié)構(gòu)包括: “頭”部分(英語:Head)、“主體”部分(英語:Body)。其中“頭”部提供關(guān)于網(wǎng)頁的信息,“主體”部分提供網(wǎng)頁的具體內(nèi)容。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
html代碼
</body>
</html>
<!--中間的內(nèi)容為注釋-->
“<!DOCTYPE html>”作用:聲明文檔的解析類型(document.compatMode),避免瀏覽器的怪異模式 (等同于開啟了標準模式) 。

CSS (層疊樣式表):是美化控件的代碼。 (英文全稱:Cascading Style Sheets)
是一種用來表現(xiàn)HTML(標準通用標記語言的一個應(yīng)用)或XML(標準通用標記語言的一個子集)等文件樣式的計算機語言。CSS不僅可以靜態(tài)地修飾網(wǎng)頁,還可以配合各種腳本語言動態(tài)地對網(wǎng)頁各元素進行格式化。
js(javascript):一種增強表現(xiàn)力的腳本語言,可以做出很多動態(tài) 及 交互性較強 的效果。
JavaScript是一種直譯式腳本語言,是一種動態(tài)類型、弱類型、基于原型的語言,內(nèi)置支持類型。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用于客戶端的腳本語言,最早是在HTML(標準通用標記語言下的一個應(yīng)用)網(wǎng)頁上使用,用來給HTML網(wǎng)頁 增加動態(tài)功能。
JavaScript基于對象(Object)和事件驅(qū)動(Event Driven)并具有安全性能的腳本語言。使用它的目的是與HTML超文本標記語言、Java腳本語言(Java小程序)一起實現(xiàn)在一個Web頁面 中 鏈接 多個對象,與Web客戶 進行交互作用。

HTML的文檔結(jié)構(gòu):
DTD-文檔類型定義(Document Type Definition)XHTML文檔結(jié)構(gòu)head元素的標記語法圖:
head元素的標記語法圖HTML語法結(jié)構(gòu)
進入主題:如果在項目中使用HTML格式(比如:現(xiàn)在大火的HTML5),往往涉及到OC與JS的交互。
html頁面 不僅僅滿足展示 功能,也能 與原生語言進行交互、相互傳值。
-
從OC到JS,可以使用“
[ stringByEvaluatingJavaScriptFromString:]”方法執(zhí)行JavaScript語句的字符串 來實現(xiàn)。
- 從JS到OC,通過UIWebView瀏覽器 攔截url請求,自定義url的方式 攔截 交互請求。
交互常見形式
[一].UIWebView Delegate
-
1.過濾 請求條件:
一般在 “-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { }” 方法里!// 禁止webview中的鏈接點擊 (用于 :??過濾 請求條件) -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { // 頁面準備加載內(nèi)容時調(diào)用,通過返回值來進行判斷是否要加載 if (webView == self.webV_2) { // 是第二個WebView if(navigationType == UIWebViewNavigationTypeLinkClicked) { //判斷點擊的是否為 鏈接 return NO; //返回“NO”,不加載到鏈接的頁面 }else{ return YES; } } else { // 其他WebView可以響應(yīng) 鏈接 return YES; } }加載效果:
第二個WebView每次點擊到響應(yīng)的類型,都會判斷是否為“鏈接”類型:如果是,不予響應(yīng)(進入鏈接頁面)。
如果點擊的 是鏈接類型,不予響應(yīng)
-
2.JavaScript處理:
一般在 “-(void)webViewDidFinishLoad:(UIWebView *)webView { }” 方法里!-(void)webViewDidFinishLoad:(UIWebView *)webView { // 加載完后觸發(fā) if (webView == self.webV_2) { // 是第二個WebView NSString * fontStr = @"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '50%'";//字體大小 // JavaScript設(shè)置:字體大小設(shè)置為 50% [self.webV_2 stringByEvaluatingJavaScriptFromString:fontStr]; } }效果:
通過JavaScript語句,設(shè)置字體大小為50%。
請參考:《UIWebView的使用》
[二].JavaScriptCore框架
添加“JavaScriptCore.frame”框架:

頭文件:#import <JavaScriptCore/JavaScriptCore.h>
步驟:
- 1.在HTML文件中,注冊 組件 (如按鈕等)。
- 2.在“
- (void)webViewDidFinishLoad:(UIWebView *)webView{ }”方法里面通過JSContext來獲取 相應(yīng)操作的key值(為 HTML文件中點擊方法的名字),并調(diào)用相應(yīng)的操作。
//JS上下文
@property (nonatomic,strong) JSContext *context;
JS調(diào)用OC的函數(shù):
方法一
使用“
self.context[@"key值] = ^{ };” 截取方法<html> <meta charset="UTF-8"> <head lang="en"> <meta charset="UTF-8"> <h1 style='color:blue'> OC與JS交互 </h1> <!-- 再本層目錄里操作,所以src不用加目錄,同樣css也是一樣的 --> <script type="text/javascript" src="" charset="UTF-8"></script> <script type="text/javascript"> function clickLink(){ } </script> <css type="text/css" charset="UTF-8"> <!-- 中間的內(nèi)容是css代碼 --> </css> <html type="text/html" src="MyCreate.js" charset="UTF-8"> <!-- 中間的內(nèi)容是html代碼 --> </html> </head> <body> <h2>標題66666</h2> <!-- 二級標題 --> <p> <p style='color:red'> <!-- 顏色改變 --> Use of JavaScript and Objective-C </p> <input type="button" value="點擊" onclick="clickLink()" /> <br/> <input type="button" value="打印" onclick="clickLink('hello!abc~')" /> <br/> <!-- 返回字符串:'你好!abc~' --> </body> </html>
在“- (void)viewDidLoad { }”里,按自己的路徑來加載“MyCreateFile.html”文件:NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"MyCreateFile.html"]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]; [self.myWebV loadRequest:request];
在“- (void)webViewDidFinishLoad:(UIWebView *)webView { }”里面://截取 JavaScript self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; self.context[@"clickLink"] = ^{ //截取按鈕點擊操作 NSArray *arg = [JSContext currentArguments]; NSLog(@"數(shù)組:%@",arg); for (id obj in arg) { NSLog(@"obj is:%@", obj); } };
打印結(jié)果:
方法二
使用
<JSExport>協(xié)議
可以直接在當前視圖控制器 里 寫上協(xié)議的響應(yīng)方法,也可以封裝一個類專門來處理。頭文件:
#import <JavaScriptCore/JavaScriptCore.h>例子??
html文件:
body部分
<body> <div id="question"> <div class="info"> <div class="topic topicFill"> <input type="hidden" class="questionId" name="questionId" value="8bf928be53b142f9bcd51324bf4a7422" /> <input type="hidden" class="defaultNum" name="answer" value="" /> <span class="topicInfo">測試數(shù)據(jù)問答題</span> <textarea name="theAnswer" placeholder="請輸入……"></textarea> </div> </div> <div class="footer"> <button class="saveBtn" id="saveBtn" onclick="saveUser()"> <span>保存</span> </button> <button class="submitBtn" id="submitBtn" onclick="submit()"> <span>提交</span> </button> </div> </div> </body>js部分
function saveUser() { //提交表單 (保存數(shù)據(jù)) //數(shù)據(jù)處理操作 // ………… //處理好之后的數(shù)據(jù) var myData = { "token" : token, "templateId" : templateId, "answers" : answer, "id" : id, "type" : type }; var myJson = JSON.stringify(myData); //console.log(JSON.stringify(myJson)); if(answer != null && answer.length >= 0){ $.ajax({ //ajax網(wǎng)絡(luò)請求 cache : true, type : "post", contentType : "application/x-www-form-urlencoded", url : '/applications/html/preservation', dataType:'json', data:{'data':myJson}, async:false, cache:false, error : function(request) { Android.requestSaveTouchEvent(false,"服務(wù)器鏈接失??!"); }, success : function(data) { if(data.Code == 0){ Android.requestSaveTouchEvent(true,data.CodeMsg); }else{ Android.requestSaveTouchEvent(false,data.CodeMsg); } } }); } } function submit() { //提交表單(上傳數(shù)據(jù)) //數(shù)據(jù)處理操作 // ………… //處理好之后的數(shù)據(jù) var myData = { "token" : token, "templateId" : templateId, "answers" : answer, "id" : id, "type" : type }; var myJson = JSON.stringify(myData); //console.log(JSON.stringify(myJson)); if(answer != null && answer.length >= 0){ $.ajax({ //ajax網(wǎng)絡(luò)請求 cache : true, type : "post", contentType : "application/x-www-form-urlencoded", url : '/applications/html/submit', dataType:'json', data:{'data':myJson}, async:false, cache:false, error : function(request) { Android.requestSubmitTouchEvent(false,"服務(wù)器鏈接失敗!"); }, success : function(data) { /* console.log(data); alert(data.CodeMsg); */ if(data.Code == 0){ $(".footer").remove(); Android.requestSubmitTouchEvent(true,data.CodeMsg); }else{ Android.requestSubmitTouchEvent(false,data.CodeMsg); } } }); } }新建“JSObject”類:
在
JSObject.h`文件:#import <Foundation/Foundation.h> #import <JavaScriptCore/JavaScriptCore.h> //首先創(chuàng)建一個實現(xiàn)了JSExport協(xié)議的協(xié)議 @protocol JSObjectProtocol <JSExport> -(void)requestSaveTouch:(BOOL)isSuccess Event:(NSString *)notice; -(void)requestSubmitTouch:(BOOL)isSuccess Event:(NSString *)notice; @end @interface JSObject : NSObject<JSObjectProtocol> @end在
JSObject.m`文件://提示框hud 三方庫 #import "MBProgressHUD.h" //APP屏幕視圖 #define APP_SCREENWINDOW [UIApplication sharedApplication].delegate.window//js調(diào)用了此處的iOS 原生方法 -(void)requestSaveTouch:(BOOL)isSuccess Event:(NSString *)notice { //保存 信息 dispatch_async(dispatch_get_main_queue(), ^{ if (isSuccess == YES) { //只顯示文字 MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:APP_SCREENWINDOW animated:YES]; hud.mode = MBProgressHUDModeText; hud.label.text = notice?notice:@"保存成功!"; hud.margin = 10.f; hud.offset = CGPointMake(0, 0.f); hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:YES afterDelay:1.5f]; hud.userInteractionEnabled = NO; } else { //只顯示文字 MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:APP_SCREENWINDOW animated:YES]; hud.mode = MBProgressHUDModeText; hud.label.text = notice?notice:@"保存錯誤!"; hud.margin = 10.f; hud.offset = CGPointMake(0, 0.f); hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:YES afterDelay:1.5f]; hud.userInteractionEnabled = NO; } }); } -(void)requestSubmitTouch:(BOOL)isSuccess Event:(NSString *)notice { //提交 信息 dispatch_async(dispatch_get_main_queue(), ^{ if (isSuccess == YES) { //只顯示文字 MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:APP_SCREENWINDOW animated:YES]; hud.mode = MBProgressHUDModeText; hud.label.text = notice?notice:@"提交成功!"; hud.margin = 10.f; hud.offset = CGPointMake(0, 0.f); hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:YES afterDelay:1.5f]; hud.userInteractionEnabled = NO; } else { //只顯示文字 MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:APP_SCREENWINDOW animated:YES]; hud.mode = MBProgressHUDModeText; hud.label.text = notice?notice:@"提交錯誤!"; hud.label.numberOfLines = 0; hud.label.lineBreakMode = NSLineBreakByCharWrapping; //可能換行 hud.margin = 10.f; hud.offset = CGPointMake(0, 0.f); hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:YES afterDelay:1.5f]; hud.userInteractionEnabled = NO; } }); }使用:
頭文件:
#import "JSObject.h"- (void)webViewDidFinishLoad:(UIWebView *)webView{ // 初始化content self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //js交互 JSObject *JsObj = [JSObject new]; self.context[@"Android"] = JsObj; //key值 }效果:
保存的情況
提交的情況
網(wǎng)絡(luò)狀態(tài)不良.png思想
OC方法:“
-(void)requestSubmitTouch:(BOOL)isSuccess Event:(NSString *)notice;//提交 信息”
等價于
JS方法:“Android.requestSubmitTouchEvent(true,data.CodeMsg);”的響應(yīng)
OC方法:“-(void)requestSaveTouch:(BOOL)isSuccess Event:(NSString *)notice;//保存 信息”
等價于
JS方法:“Android.requestSaveTouchEvent(true,data.CodeMsg);”的響應(yīng)
總結(jié):書寫時JSObject的方法,只要保證所傳遞的數(shù)據(jù)類型 相同、名字連起來 相同即可??!
安卓端java書寫:
/** * 與js交互時用到的方法,在js里直接調(diào)用的 */ @JavascriptInterface public void requestSaveTouchEvent(boolean b,String a) { if(b){ doShowToast("保存成功"); isSave=true; }else { doShowToast(a); } } @JavascriptInterface public void requestSubmitTouchEvent(boolean b,String a) { if(b){ doShowToast("提交成功"); isSubmit=true; AfterClassReflectActivity.this.finish(); }else { doShowToast(a); } }道理一樣,以相應(yīng)的函數(shù) 響應(yīng)JavaScript的操作!
OC調(diào)用JS的函數(shù):
執(zhí)行JavaScript語句! 類比FMDB~
在“- (void)viewDidLoad { }”里面:// 在界面上添加一個按鈕,實現(xiàn):OC端控制h5,實現(xiàn)彈出alert提示框 UIButton * alertBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 500, 100, 30)]; [alertBtn setTitle:@"按鈕" forState:UIControlStateNormal]; alertBtn.backgroundColor = [UIColor redColor]; [alertBtn addTarget:self action:@selector(showHtml5Alert) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview: alertBtn];//提示框alert 展示 - (void)showHtml5Alert { //要將script的alert()方法轉(zhuǎn)化為string類型 NSString * alertJs=@"alert('Hello Word')"; //警告框 //alertJs=@"confirm('Hello Word')"; //確認框 //alertJs=@"prompt('Hello Word','123456')"; //提示框 + 文字輸入框 [self.context evaluateScript:alertJs]; }
三方庫(WebViewJavaScriptBridge)
使用步驟
- 1.創(chuàng)建WebView
- 2.創(chuàng)建WebViewJavaScriptBridge對象
- 3.注冊JS要調(diào)用的Native
handlerName:需要調(diào)用的JS名字(無后綴)
handler:需要OC進行的操作
自己并沒有熟練使用WebViewJavaScriptBridge三方庫!公司的項目也只用了<JSExport>協(xié)議 就解決問題了!
以后熟練了WebViewJavaScriptBridge,再來補上吧!
可參考:WebViewJavascriptBridge-Obj-C和JavaScript互通消息的橋梁
很久就想寫一下JavaScript的東西!??????
公司的項目里面使用到了,終于寫了一篇!











