首先要理清一下關系:
HTML:一些網頁控件。
超文本標記語言,標準通用標記語言(SGM或SGML)下的一個應用。
“超文本”就是指 頁面內可以包含圖片、鏈接,甚至音樂、程序 等非文字元素。
超文本標記語言的結構包括: “頭”部分(英語:Head)、“主體”部分(英語:Body)。其中“頭”部提供關于網頁的信息,“主體”部分提供網頁的具體內容。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
html代碼
</body>
</html>
<!--中間的內容為注釋-->
“<!DOCTYPE html>
”作用:聲明文檔的解析類型(document.compatMode),避免瀏覽器的怪異模式 (等同于開啟了標準模式) 。
CSS (層疊樣式表):是美化控件的代碼。 (英文全稱:Cascading Style Sheets)
是一種用來表現HTML(標準通用標記語言的一個應用)或XML(標準通用標記語言的一個子集)等文件樣式的計算機語言。CSS不僅可以靜態地修飾網頁,還可以配合各種腳本語言動態地對網頁各元素進行格式化。
js(javascript):一種增強表現力的腳本語言,可以做出很多動態 及 交互性較強 的效果。
JavaScript是一種直譯式腳本語言,是一種動態類型、弱類型、基于原型的語言,內置支持類型。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用于客戶端的腳本語言,最早是在HTML(標準通用標記語言下的一個應用)網頁上使用,用來給HTML網頁 增加動態功能。
JavaScript基于對象(Object)和事件驅動(Event Driven)并具有安全性能的腳本語言。使用它的目的是與HTML超文本標記語言、Java腳本語言(Java小程序)一起實現在一個Web頁面 中 鏈接 多個對象,與Web客戶 進行交互作用。
HTML的文檔結構:
DTD-文檔類型定義(Document Type Definition)XHTML文檔結構head元素的標記語法圖:
head元素的標記語法圖HTML語法結構
進入主題:如果在項目中使用HTML格式(比如:現在大火的HTML5),往往涉及到OC與JS的交互。
html頁面 不僅僅滿足展示 功能,也能 與原生語言進行交互、相互傳值。
-
從OC到JS,可以使用“
[ stringByEvaluatingJavaScriptFromString:]
”方法執行JavaScript語句的字符串 來實現。
- 從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 { // 頁面準備加載內容時調用,通過返回值來進行判斷是否要加載 if (webView == self.webV_2) { // 是第二個WebView if(navigationType == UIWebViewNavigationTypeLinkClicked) { //判斷點擊的是否為 鏈接 return NO; //返回“NO”,不加載到鏈接的頁面 }else{ return YES; } } else { // 其他WebView可以響應 鏈接 return YES; } }
加載效果:
第二個WebView每次點擊到響應的類型,都會判斷是否為“鏈接”類型:如果是,不予響應(進入鏈接頁面)。
如果點擊的 是鏈接類型,不予響應
-
2.JavaScript處理:
一般在 “-(void)webViewDidFinishLoad:(UIWebView *)webView { }
” 方法里!-(void)webViewDidFinishLoad:(UIWebView *)webView { // 加載完后觸發 if (webView == self.webV_2) { // 是第二個WebView NSString * fontStr = @"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '50%'";//字體大小 // JavaScript設置:字體大小設置為 50% [self.webV_2 stringByEvaluatingJavaScriptFromString:fontStr]; } }
效果:
通過JavaScript語句,設置字體大小為50%。
請參考:《UIWebView的使用》
[二].JavaScriptCore框架
添加“JavaScriptCore.frame”框架:
頭文件:#import <JavaScriptCore/JavaScriptCore.h>
步驟:
- 1.在HTML文件中,注冊 組件 (如按鈕等)。
- 2.在“
- (void)webViewDidFinishLoad:(UIWebView *)webView{ }
”方法里面通過JSContext來獲取 相應操作的key值(為 HTML文件中點擊方法的名字),并調用相應的操作。
//JS上下文
@property (nonatomic,strong) JSContext *context;
JS調用OC的函數:
方法一
使用“
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"> <!-- 中間的內容是css代碼 --> </css> <html type="text/html" src="MyCreate.js" charset="UTF-8"> <!-- 中間的內容是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(@"數組:%@",arg); for (id obj in arg) { NSLog(@"obj is:%@", obj); } };
打印結果:
方法二
使用
<JSExport>
協議
可以直接在當前視圖控制器 里 寫上協議的響應方法,也可以封裝一個類專門來處理。頭文件:
#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">測試數據問答題</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() { //提交表單 (保存數據) //數據處理操作 // ………… //處理好之后的數據 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網絡請求 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,"服務器鏈接失敗!"); }, success : function(data) { if(data.Code == 0){ Android.requestSaveTouchEvent(true,data.CodeMsg); }else{ Android.requestSaveTouchEvent(false,data.CodeMsg); } } }); } } function submit() { //提交表單(上傳數據) //數據處理操作 // ………… //處理好之后的數據 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網絡請求 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,"服務器鏈接失敗!"); }, 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> //首先創建一個實現了JSExport協議的協議 @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調用了此處的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值 }
效果:
保存的情況
提交的情況
網絡狀態不良.png思想
OC方法:“
-(void)requestSubmitTouch:(BOOL)isSuccess Event:(NSString *)notice;//提交 信息
”
等價于
JS方法:“Android.requestSubmitTouchEvent(true,data.CodeMsg);
”的響應
OC方法:“-(void)requestSaveTouch:(BOOL)isSuccess Event:(NSString *)notice;//保存 信息
”
等價于
JS方法:“Android.requestSaveTouchEvent(true,data.CodeMsg);
”的響應
總結:書寫時JSObject的方法,只要保證所傳遞的數據類型 相同、名字連起來 相同即可!!
安卓端java書寫:
/** * 與js交互時用到的方法,在js里直接調用的 */ @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); } }
道理一樣,以相應的函數 響應JavaScript的操作!
OC調用JS的函數:
執行JavaScript語句! 類比FMDB~
在“- (void)viewDidLoad { }
”里面:// 在界面上添加一個按鈕,實現:OC端控制h5,實現彈出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()方法轉化為string類型 NSString * alertJs=@"alert('Hello Word')"; //警告框 //alertJs=@"confirm('Hello Word')"; //確認框 //alertJs=@"prompt('Hello Word','123456')"; //提示框 + 文字輸入框 [self.context evaluateScript:alertJs]; }
三方庫(WebViewJavaScriptBridge)
使用步驟
- 1.創建WebView
- 2.創建WebViewJavaScriptBridge對象
- 3.注冊JS要調用的Native
handlerName:需要調用的JS名字(無后綴)
handler:需要OC進行的操作
自己并沒有熟練使用WebViewJavaScriptBridge三方庫!公司的項目也只用了<JSExport>協議 就解決問題了!
以后熟練了WebViewJavaScriptBridge,再來補上吧!
可參考:WebViewJavascriptBridge-Obj-C和JavaScript互通消息的橋梁
很久就想寫一下JavaScript的東西!??????
公司的項目里面使用到了,終于寫了一篇!