iOS WKWebView 不显示 javascript alert() 对话框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26898941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS WKWebView not showing javascript alert() dialog
提问by Charlie
I am having some trouble getting a WKWebView in iOS 8 to display an alert dialog that is called from Javascript. After creating a standard WKWebView and loading an HTML file, I have a button on the page that creates a simple alert with some text. This works in UIWebView and in Google Chrome/Safari, but does not appear to be working in WKWebView. Any help is appreciated.
我在 iOS 8 中获取 WKWebView 以显示从 Javascript 调用的警报对话框时遇到了一些麻烦。创建标准 WKWebView 并加载 HTML 文件后,我在页面上有一个按钮,用于创建带有一些文本的简单警报。这适用于 UIWebView 和 Google Chrome/Safari,但似乎不适用于 WKWebView。任何帮助表示赞赏。
My setup is as follows:
我的设置如下:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.allowsInlineMediaPlayback = YES;
config.mediaPlaybackRequiresUserAction = false;
_wkViewWeb = [[WKWebView alloc] initWithFrame:_viewWeb.frame config];
_wkViewWeb.scrollView.scrollEnabled = NO;
NSString *fullURL = @"file://.../TestSlide.html";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[_wkViewWeb loadRequest:request];
The html has the following function:
html具有以下功能:
<SCRIPT Language="JavaScript">
function alertTest() {
alert("Testing Alerts");
}
</SCRIPT>
And a button:
还有一个按钮:
<b>Test Alerts: <input type="button" value="Alert Popup" onclick="alertTest()"><br></b> <br>
This setup works in UIWebView and in regular browsers, but does not work in WKWebView. Am I missing something in the configuration? Should I be using one of the WK delegates to control the alert/confirm dialog behavior? Thank you.
此设置适用于 UIWebView 和常规浏览器,但不适用于 WKWebView。我在配置中遗漏了什么吗?我应该使用 WK 代表之一来控制警报/确认对话框行为吗?谢谢你。
回答by Nikola Lajic
To solve this you need a WKUIDelegate for your web view. It is the duty of the delegate to decide if an alert should be displayed, and in what way. You need to implement this for alert, confirm and text input (prompt).
为了解决这个问题,您需要一个 WKUIDelegate 用于您的 Web 视图。代表有责任决定是否应显示警报以及以何种方式显示。您需要为警报、确认和文本输入(提示)实现此功能。
Here is sample code without any validation of the page url or security features:
这是没有对页面 url 或安全功能进行任何验证的示例代码:
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
More in the Official Documentation
更多官方文档
回答by Crashalot
Swift 3with all 3 optional functions implemented:
Swift 3 实现了所有 3 个可选功能:
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
completionHandler()
}))
present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(false)
}))
present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (String?) -> Void) {
let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .actionSheet)
alertController.addTextField { (textField) in
textField.text = defaultText
}
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
if let text = alertController.textFields?.first?.text {
completionHandler(text)
} else {
completionHandler(defaultText)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(nil)
}))
present(alertController, animated: true, completion: nil)
}
回答by bendytree
Just to expand a bit, WKWebViewrequires you to show alerts, prompts, and confirms yourself. Do this by becoming a WKUIDelegate:
只是稍微扩展一下,WKWebView需要您显示警报、提示和确认自己。通过成为一个来做到这一点WKUIDelegate:
#import <WebKit/WebKit.h>
@interface MyController : UIViewController<WKUIDelegate>
Then assign the delegate:
然后分配委托:
web.UIDelegate = self;
Then you need to actually implement alert, prompt, and confirm. I create WKWebViewPanelManager.h/mas an easy implementation, so here's what I do:
那么就需要实际实现alert、prompt、confirm。我创建WKWebViewPanelManager.h/m作为一个简单的实现,所以这就是我要做的:
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
[WKWebViewPanelManager presentAlertOnController:self.view.window.rootViewController title:@"Alert" message:message handler:completionHandler];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
[WKWebViewPanelManager presentConfirmOnController:self.view.window.rootViewController title:@"Confirm" message:message handler:completionHandler];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
[WKWebViewPanelManager presentPromptOnController:self.view.window.rootViewController title:@"Prompt" message:prompt defaultText:defaultText handler:completionHandler];
}
Of course, it's up to you to filter out bad alert/confirm/prompt requests.
当然,过滤掉错误的警报/确认/提示请求取决于您。
回答by Stafford Williams
And here's that in swift:
这是swift 中的:
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: message,
message: nil,
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .cancel) {
_ in completionHandler()}
)
self.present(alertController, animated: true, completion: nil)
}
回答by Muhammad Maqsood
- Implement the protocol to your WKWebview container controller. WKUIDelegate
Add preference to WKWebviewto enable javascript in viewDidLoad()as.
// enable JS webView.configuration.preferences.javaScriptEnabled = trueRegister WKWebviewUI Delegate in viewDidLoad()as
self.webView.uiDelegate = selfImplement the below delegate in your class.
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alertController = UIAlertController(title: message,message: nil,preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "OK", style: .cancel) {_ in completionHandler()}) self.present(alertController, animated: true, completion: nil) }
- 将协议实现到您的 WKWebview 容器控制器。WKUID代表
向WKWebview添加首选项以在viewDidLoad() 中启用 javascript 。
// enable JS webView.configuration.preferences.javaScriptEnabled = true在viewDidLoad() 中注册WKWebviewUI 委托为
self.webView.uiDelegate = self在您的班级中实现以下委托。
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alertController = UIAlertController(title: message,message: nil,preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "OK", style: .cancel) {_ in completionHandler()}) self.present(alertController, animated: true, completion: nil) }
回答by Hassan Taleb
Here is the code in Swift 4.2
这是Swift 4.2 中的代码
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: message, message: nil,
preferredStyle: UIAlertController.Style.alert);
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel) {
_ in completionHandler()}
);
self.present(alertController, animated: true, completion: {});
}

