UIWebView和js交互
來源:程序員人生 發(fā)布時(shí)間:2015-08-10 08:51:20 閱讀次數(shù):3244次
之前做過1個(gè)項(xiàng)目,里面觸及到顯示公式之類的東西就必須要在項(xiàng)目里面嵌入網(wǎng)頁,最麻煩的就是網(wǎng)頁需要在本地自己拼湊成html,然后再使用UIWebView加載出來,這里面就觸及到了1些關(guān)于OC和JavaScript交互的問題,對第1次接觸這些的人,還是會(huì)走1些彎路。我在此把自己學(xué)習(xí)的分享出來,希望幫到1些人。
分兩部份介紹,第1部份是加載本地網(wǎng)頁。然落后行交互。第2部份是加載服務(wù)器的網(wǎng)頁落后行交互。
1 加載本地網(wǎng)頁(demo下載地址}
加載本地網(wǎng)頁的話,由于網(wǎng)頁都是自己寫,我們可以把需要的要求參數(shù)都提早寫好。這樣在OC代碼里面就能夠直接的和網(wǎng)頁交互。
OC和js交互的原理是網(wǎng)頁發(fā)起1個(gè)要求,然后WebView截獲這個(gè)要求,對這個(gè)要求的話可以是很多種的。我的Demo里面也總結(jié)了兩種不同的方法。
第1種
<script type="text/javascript">
function sendCommand(cmd,param){
var url="zjq:"+cmd+":"+param;
document.location = url;
}
</script>
第2種
<script language="javascript">
function loadURL(url) {
var iFrame;
iFrame = document.createElement("iframe");
iFrame.setAttribute("src", url);
iFrame.setAttribute("style", "display:none;");
iFrame.setAttribute("height", "0px");
iFrame.setAttribute("width", "0px");
iFrame.setAttribute("frameborder", "0");
document.body.appendChild(iFrame);
// 發(fā)起要求后這個(gè)iFrame就沒用了,所以把它從dom上移除掉
iFrame.parentNode.removeChild(iFrame);
iFrame = null;
}
function check() {
loadURL("zjq:zjqjjqzjq");
}
</script>
用的比較多也比較簡潔的是第1種,第2種的話是發(fā)起1個(gè)假的要求,1句話,都是為了網(wǎng)頁能夠刷新1下,WebView的拜托才會(huì)被調(diào)用,才能夠攔截到要求,然后做出相應(yīng)的處理。
1.在界面里面添加1個(gè)1個(gè)UIWebView和1個(gè)按鈕,按鈕用于OC對網(wǎng)頁發(fā)起操作
currentY = self.navigationController.navigationBar.frame.size.height;
screen = [UIScreen mainScreen].bounds.size;
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, currentY, screen.width, screen.height⑴00)];
self.automaticallyAdjustsScrollViewInsets = NO;
_webView.delegate = self;
// _webView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_webView];
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(50, screen.height⑸0, screen.width⑴00, 30)];
[button addTarget:self action:@selector(appTojs) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"app向網(wǎng)頁發(fā)送消息" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:button];
2.加載html頁面
加載頁面的方式也很多
NSString * path = [[NSBundle mainBundle] bundlePath];
NSURL * baseURL = [NSURL fileURLWithPath:path];
NSString * htmlFile = [[NSBundle mainBundle] pathForResource:@"Test" ofType:@"html"];
NSString * htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:(NSUTF8StringEncoding) error:nil];
// 從本地加載1個(gè)html文件。
[self.webView loadHTMLString:htmlString baseURL:baseURL];
這類方式把html當(dāng)作文件加載
NSString * htmlPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"index.html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:htmlPath]]];
這類方法則是相當(dāng)于發(fā)起1個(gè)要求
3.實(shí)現(xiàn)拜托函數(shù)(js對oc交互)
//當(dāng)網(wǎng)頁視圖被唆使載入內(nèi)容而得到通知。應(yīng)當(dāng)返回YES,這樣會(huì)進(jìn)行加載
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSURL *url = [request URL];
if ([[url scheme] isEqualToString:@"zjq"]) {
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"通知" message:[NSString stringWithFormat:@"%@%@",@"發(fā)起要求的url是:",[url absoluteString]]delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
//多個(gè)
// NSString *requestString = [[request URL] absoluteString];//獲得要求的絕對路徑.
// NSArray *components = [requestString componentsSeparatedByString:@":"];//提交要求時(shí)候分割參數(shù)的分隔符
// if ([components count] > 1 && [(NSString *)[components objectAtIndex:0] isEqualToString:@"testapp"]) {
// //過濾要求是不是是我們需要的.不需要的要求不進(jìn)入條件
// if([(NSString *)[components objectAtIndex:1] isEqualToString:@"alert"])
//
return YES;
}
這個(gè)返回值1定要是YES的,否則加載不出來,對上面這個(gè)拜托方法是用來處理js發(fā)起的要求,對要求的判斷,也是可使用兩種不同的方法。上面的源碼里面都已給出。個(gè)人更喜歡第1種,如果有多種不同的要求,又有很對子要求的話第2種應(yīng)當(dāng)好1些。
//開始要求調(diào)用的方法,可以加個(gè)唆使器
- (void)webViewDidStartLoad:(UIWebView *)webView{
}
//結(jié)束要求調(diào)用的方法,可以加個(gè)唆使器
- (void)webViewDidFinishLoad:(UIWebView *)webView{
}
//加載失敗的方法
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(@"error是%@",error);
}
4.oc對js交互
oc對html進(jìn)行修改的話,我們使用1個(gè)方法就能夠。stringByEvaluatingJavaScriptFromString,蘋果也就只給了這1個(gè)方法。
- (void)appTojs{
NSString * js = @" var p = document.createElement('p'); p.innerText = '增加1行';document.body.appendChild(p);";
[self.webView stringByEvaluatingJavaScriptFromString:js];
}
2 加載網(wǎng)絡(luò)服務(wù)器的頁面(demo下載地址)
頁面加載本身沒有多大的難度,我這里主要介紹的是頁面加載結(jié)束后,如何把我們的js代碼注入到原來的html頁面里面,我們才可以知道相應(yīng)的要求的scheme等的相應(yīng)信息。否則我的拜托函數(shù)里面沒有判斷的根據(jù)嘛。
- (void)webViewDidFinishLoad:(UIWebView *)webView{
NSString * string = [webView stringByEvaluatingJavaScriptFromString:@"var script = document.createElement('script');"
"script.type = 'text/javascript';"
"script.text = "function sendCommand(cmd,param){"
"var url='zjq:'+cmd+':'+param;"
"document.location = url;"
"}"
"var btn = document.getElementById('test');"
"btn.onclick = function(){"
"sendCommand('zjq','jump');"
"}" ;"
"alert(script.text);"
"document.getElementsByTagName('html')[0].appendChild(script);"];
NSLog(@"返回的消息是%@",string);
//答應(yīng)全部頁面可以看到我們得代碼是不是加進(jìn)去了
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
NSString *text = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.innerHTML"];
NSLog(@"url是,%@,text%@",currentURL,text);
}
這里主要的去區(qū)分就是在加載結(jié)束后我得把我得js代碼注入到原網(wǎng)頁中
不的不提示1下上面的js代碼,如果你不是很熟習(xí)的話,修改1些參數(shù)就能夠,OC里面要不把js弄錯(cuò)還真是困難,那末多引號(hào),少1個(gè)都有可能出問題。反正我弄了1個(gè)下午。改來改去總是出錯(cuò)。可能和我不太熟習(xí)JS有很大的關(guān)系。這個(gè)注入以后,其他的個(gè)本地加載沒多大區(qū)分了。不過有些網(wǎng)頁是加了限制不讓注入的。團(tuán)隊(duì)在開發(fā)的時(shí)候肯定需要調(diào)和好。我demo里面是使用了百度。代碼是進(jìn)去了,但是還是運(yùn)行不了,百度應(yīng)當(dāng)是攔截了它。
因而Demo就是現(xiàn)在這個(gè)樣了,我用了1個(gè)本地的頁面的,但是和從
服務(wù)器加載出來的差不多。里面我并沒有提早寫好要求的地址之類的。 是使用OC給html注入的。
參考資料地址時(shí)間有些久我都不記得了,這里不在列出,謝謝先輩們,加了很多個(gè)人理解,總覺得還是有些問題。不足的地方請批評指正。
裝載請著名原創(chuàng)地址 :http://blog.csdn.net/zhouzhoujianquan/article/details/45397945
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)