由于H5具有跨平臺的優(yōu)勢,在很多情況下可能會使用到,但是對于混編有時候會是必要的。
1> 使用OC調(diào)用javascript代碼
首先要了解一下web的加載;
在OC中,加載網(wǎng)頁的控件是UIWebView;
一般我們需要做的是先加載原來的Web,然后再進(jìn)行處理,這樣的話,就會用到UIWebView的代理方法。
// 這個方法是網(wǎng)頁加載完畢之后進(jìn)行調(diào)用
- (void)webViewDidFinishLoad:(UIWebView *)webView;
當(dāng)網(wǎng)頁加載完畢之后,就可以很輕松的拿到當(dāng)前加載網(wǎng)頁的<body>,這樣的話我們就可以通過執(zhí)行js代碼進(jìn)行處理原來的網(wǎng)頁
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML;"];
通過上面這個方法可以獲得網(wǎng)頁的結(jié)構(gòu),在自己不確定網(wǎng)頁結(jié)構(gòu)的情況下,可以打印出來看一下,這樣就可以很容易找到自己要處理的內(nèi)容。
然后執(zhí)行js代碼,可以通過下面的方法進(jìn)行加載js代碼,
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
要注意的是參數(shù)是字符串,所以我們需要把代碼包裝在字符串里面
NSMutableString *js = [NSMutableString stringWithString:@"這里寫js代碼"];
多行js代碼之間可以使用反斜線(\)連接。舉個栗子:
NSMutableString *js = [NSMutableString stringWithString:@"\
var footer = document.getElementsByTagName('footer')[0];\
footer.parentNode.removeChild(footer);\
var header = document.getElementsByTagName('header')[0];\
header.parentNode.removeChild(header);\
"];
然后執(zhí)行js
[webView stringByEvaluatingJavaScriptFromString:js];
這樣就可以將自己添加的js添加到加載到得網(wǎng)頁中。
2>使用JS調(diào)用OC的代碼
使用JS調(diào)用OC并非像上面的那么簡單.這里會使用UIWebView的另外的一個代理方法
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
上面這個方法在每次進(jìn)行加載網(wǎng)頁的時候都會執(zhí)行,可以監(jiān)聽每一次webView發(fā)送的請求,如果返回值是 YES, 則說明可以進(jìn)行加載網(wǎng)頁, 如果返回的是 NO, 則說明禁止加載該網(wǎng)頁.
那這個方法應(yīng)該怎么使用呢?
因?yàn)樵贘S中無法直接調(diào)用OC的方法,我們的思路是將js中的事件轉(zhuǎn)化成自定義的一種協(xié)議,當(dāng)執(zhí)行協(xié)議時,webView的代理方法進(jìn)行監(jiān)聽,如果自己需要的方法,則可以執(zhí)行OC方法.
下面看了一段HTML代碼
<body>
<div>
<button onclick="fn_click();">按鈕1</button>
</div>
<script type="text/javascript">
function fn_click() {
// 自定義協(xié)議,進(jìn)行動態(tài)跳轉(zhuǎn)
window.location.href = 'dz://click';
}
</script>
</body>
然后對網(wǎng)頁進(jìn)行監(jiān)聽
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *url = request.URL.absoluteString;
// 判斷請求是否是自定義的,如果是自定義的,則進(jìn)行處理
NSRange range = [url rangeOfString:@"dz://"];
NSUInteger loc = range.location;
if (loc != NSNotFound) {
NSString *method = [url substringFromIndex:loc + range.length]; // 取出JS方法的方法名
SEL sel = NSSelectorFromString(method); // 將JS方法名轉(zhuǎn)化為OC的方法名
[self performSelector:sel withObject:nil];
}
return YES;
}
通過上面的一段代碼,就可以在OC中調(diào)用JS方法。
- (void)click {
NSLog(@“點(diǎn)擊了btn”);
}