WKWebView中js无法主动弹出弹框,因此需要通过WebKit提供的代理方法,在navite层弹出弹框,并且将弹框的响应返回给web层
- 代理方法说明
- 具体实现
效果:
1、代理方法
WKUIDelegate协议中提供了弹框方法,包括alert、textInput、confirm。
该协议还提供了大量的与web交互的方法,可查看WKWebView详解(二)- WebKit框架认识
//显示JavaScript的alert弹框面板。
- webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:
//显示JavaScript的confirm弹框面板。
- webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:
//显示JavaScript的textInput弹框面板。
webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:
2、具体实现
2.1 写一个简单的网页
这里增加了弹框响应给web层的操作,这里仅做简单的弹出显示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>标题</title>
<script>
function alertTest(){
window.alert("message");
}
function confirmTest(){
var result = window.confirm("message");
if (result == true){
alert("true");
} else {
alert ("flase");
}
}
function inputTest(){
var result = window.prompt("message","嘿哈!");
if (result != null && result != ""){
alert(result);
}
}
</script>
</head>
<body>
<button type="button" onclick="alertTest()" style="color:blue;margin-left:40px;font-size:50px;">alert</button>
<button type="button" onclick="confirmTest()" style="color:red;margin-left:40px;font-size:50px;">confirm</button>
<button type="button" onclick="inputTest()" style="color:green;margin-left:40px;font-size:50px;">input</button>
</body>
</html>
2.2 加载网页
#import "ViewController.h"
#import <WebKit/WebKit.h>
@interface ViewController ()<WKURLSchemeHandler, WKNavigationDelegate, WKUIDelegate>
@property (nonatomic, strong) WKWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
CGRect myFrame = self.view.frame;
self.webView = [[WKWebView alloc] initWithFrame:myFrame configuration:configuration];
self.webView.UIDelegate = self;
NSString *path = [[NSBundle mainBundle ] pathForResource:@"first" ofType:@"html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
[self.view addSubview:self.webView];
}
说明:
- 弹出弹框需要遵守WKUIDelegate协议
- 通过loadRequest方法直接加载本地文件
2.3 弹框实现
//alert
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
if (!message || message.length == 0) {
completionHandler();
return;
}
UIAlertController *controller = [UIAlertController alertControllerWithTitle:webView.title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}];
[controller addAction:okAction];
[self presentViewController:controller animated:YES completion:nil];
}
//confirm
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
if (!message || message.length == 0) {
completionHandler(NO);
return;
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:webView.title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}];
UIAlertAction * confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}];
[alertController addAction:cancelAction];
[alertController addAction:confirmAction];
[self presentViewController:alertController animated:YES completion:nil];
}
//input
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
if (!prompt || prompt.length == 0) {
completionHandler(@"");
return;
}
NSString *placeholderText = @"请输入文本";
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:webView.title message:prompt preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
textField.placeholder = placeholderText;
}];
UIAlertAction * action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text ? : @"");
}];
[alertController addAction:action];
[self presentViewController:alertController animated:YES completion:nil];
}
说明:
- 如果传入的message为空,也需要有个空返回
- 在代理方法中只需要按照OC方式实现弹框即可