印言
最近接到一個(gè)需求:監(jiān)聽網(wǎng)頁(yè)的按鈕的點(diǎn)擊事件,并且網(wǎng)頁(yè)不是我們招呼一聲對(duì)方就能改的非洲。那么一切的故事從這里開始了。正文部分主要圍繞監(jiān)聽網(wǎng)頁(yè)的事件為主線。
正文
WKWebView加載本地html頁(yè)面拐纱,
搭建UI做準(zhǔn)備工作。
NSString *path = [[NSBundle mainBundle] pathForResource:@"oc&js.html" ofType:nil];
[_wkWeb loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
html和oc各創(chuàng)建兩個(gè)按鈕哥倔,倆個(gè)按鈕分別測(cè)試無(wú)參數(shù)和有參數(shù)消息的傳遞秸架。
<h2>是H5按鈕</h2>
<button type="button" onclick="js2oc1()">js調(diào)用oc的按鈕1</button>
<button type="button" onclick="js2oc2('Gavin','18')">js調(diào)用oc的按鈕2</button>
<!-- 用于顯示oc點(diǎn)擊事件的結(jié)果 -->
<h1 id=labelId>label</h1>
// OC的按鈕
_button1 = [[UIButton alloc] initWithFrame:CGRectMake(100, self.view.bounds.size.height/2 + 100, 200,40)];
[_button1 setTitle:@"oc2js無(wú)參" forState:UIControlStateNormal];
_button1.backgroundColor = [UIColor grayColor];
[_button1 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_button1 addTarget:self action:@selector(button1Click:)forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_button1];
_button2 = [[UIButton alloc]initWithFrame:CGRectMake(100,self.view.bounds.size.height/2 + 150, 200,40)];
[_button2 setTitle:@"oc2js有參"forState:UIControlStateNormal];
_button2.backgroundColor = [UIColor grayColor];
[_button2 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_button2 addTarget:self action:@selector(button2Click:)forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_button2];
1. JS調(diào)用OC方法
JS按鈕綁定的函數(shù)內(nèi)給OC發(fā)送消息window.webkit.messageHandlers.這個(gè)位置是消息名稱.postMessage();
,消息名稱在oc里注冊(cè)js消息的時(shí)候用到咆蒿。具體如下:
// JS給OC發(fā)送消息
function js2oc1() {
window.webkit.messageHandlers.noParamsFunction.postMessage('我是js方法傳過(guò)來(lái)的數(shù)據(jù)');
}
function js2oc2(x,y) {
window.webkit.messageHandlers.haveParamsFunction.postMessage({name:x,age:y});
}
WKWebView 需要遵守WKScriptMessageHandler
協(xié)議东抹,并注冊(cè)JS消息:
WKUserContentController *_userContentController = [[WKUserContentController alloc] init];
// 遵守WKScriptMessageHandler協(xié)議。注冊(cè)JS消息沃测,name必須JS發(fā)送消息時(shí)的名字對(duì)應(yīng)
[_userContentController addScriptMessageHandler:self name:@"noParamsFunction"];
[_userContentController addScriptMessageHandler:self name:@"haveParamsFunction"];
WKWebViewConfiguration *_configuration = [[WKWebViewConfiguration alloc] init];
_configuration.userContentController = _userContentController;
_wkWeb = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width,self.view.bounds.size.height/2 - 20) configuration:_configuration];
WKScriptMessageHandler協(xié)議只有一個(gè)方法:
@protocol WKScriptMessageHandler <NSObject>
@required
/*! @abstract Invoked when a script message is received from a webpage.
@param userContentController The user content controller invoking the
delegate method.
@param message The script message received.
*/
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
@end
實(shí)現(xiàn)該方法。方法功能就是接受JS消息蒂破。
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
// WKScriptMessage 類的name屬性是消息名稱馏谨,body是發(fā)送的數(shù)據(jù)
NSLog(@"message.name:%@", message.name);
NSLog(@"message.body:%@", message.body);
}
寫了這么多我們運(yùn)行一遍看效果:
2. OC調(diào)用JS函數(shù)
WKWebView 有個(gè)方法
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
可以實(shí)現(xiàn)執(zhí)行JS代碼,原理比較像html頁(yè)面注入代碼附迷。這方法調(diào)用一般在頁(yè)面加載完成后惧互。如果不是寫在按鈕點(diǎn)擊事件內(nèi)哎媚,你可以選在在WKWebView的WKNavigationDelegate
協(xié)議代理方法- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;
內(nèi)調(diào)用。
貼上剛加載完的頁(yè)面做對(duì)比壹哺。白色背景的上半頁(yè)面是html區(qū)域抄伍,灰色背景的下半頁(yè)面是OC控件。下面的OC按鈕被點(diǎn)擊后html區(qū)域的label字樣會(huì)改變管宵。
按鈕點(diǎn)擊事件內(nèi)調(diào)用:
- (void)button1Click:(UIButton *)button {
// OC給JS發(fā)送消息
[_wkWeb evaluateJavaScript:@"oc2js1()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
NSLog(@"error %@", error);
}];
}
- (void)button2Click:(UIButton *)button {
// OC給JS發(fā)送消息
[_wkWeb evaluateJavaScript:@"oc2js2('你','好')" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
NSLog(@"error %@", error);
}];
}
demo工程可以到我的Github下載截珍。
總結(jié)
我們的目的想監(jiān)聽遠(yuǎn)程網(wǎng)頁(yè)按鈕點(diǎn)擊事件到這里還是不能實(shí)現(xiàn)。別人不會(huì)在自己的網(wǎng)頁(yè)JS代碼中給你添加window.webkit.messageHandlers.(messagename).postMessage
讓你調(diào)用箩朴。所以在下一章中繼續(xù)岗喉。
WKWebview與JavaScript 交互(二)監(jiān)聽遠(yuǎn)程網(wǎng)頁(yè)點(diǎn)擊事件