在iOS中更改JavaScript警报对话框标题

时间:2012-05-21 07:55:11

标签: javascript ios uiwebview

是否可以在iPhone的UIWebview中更改JavaScript提醒标题?

7 个答案:

答案 0 :(得分:57)

基本上你不能改变标题,但最近我找到了一种显示没有标题的警告对话框的方法。

var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", 'data:text/plain,');
document.documentElement.appendChild(iframe);
window.frames[0].window.alert('hello');
iframe.parentNode.removeChild(iframe);

答案 1 :(得分:15)

我为这个问题提出了三个独立的解决方案。生产代码的最佳解决方案是@Martin H描述的解决方案。我对此的唯一补充是展示如何实现它的具体示例。

我的其他解决方案依赖于UIWebView的未记录行为,但不需要对内容/ JS进行任何更改。

解决方案1 ​​:这是一个展示@Martin H提出的技术的具体示例。这可能是最佳解决方案,因为它不依赖于UIWebView / {{1}无证行为。

UIAlertView

解决方案2:首先,我要说在生产代码中我绝不会亲自使用以下解决方案。实现此功能的最佳方法是做@Martin H在他的回答中建议的内容,或者可能是@twk建议如果空标题实际上是所需的。如果您无法控制Web内容本身,也许您可​​以在加载内容后注入@Martin H的代码。

尽管如此,如果我们做出一些假设,这是可以实现的。首先,Javascript @interface TSViewController () <UIWebViewDelegate> @end @implementation TSViewController - (UIWebView*) webView { return (UIWebView*) self.view; } - (void) loadView { UIWebView* wv = [[UIWebView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)]; wv.delegate = self; wv.scalesPageToFit = YES; self.view = wv; } - (void) viewDidLoad { [super viewDidLoad]; [self.webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: @"http://www.craigslist.org"]]]; } - (void) webViewDidFinishLoad: (UIWebView *) webView { // inject some js to re-map window.alert() // ideally just do this in the html/js itself if you have control of that. NSString* js = @"window.alert = function(message) { window.location = \"http://action/alert?message=\" + message; }"; [webView stringByEvaluatingJavaScriptFromString: js]; // trigger an alert. for demonstration only: [webView stringByEvaluatingJavaScriptFromString: @"alert('hello, world');" ]; } - (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL* url = request.URL; // look for our custom action to come through: if ( [url.host isEqualToString: @"action"] && [url.path isEqualToString: @"/alert"] ) { // parse out the message NSString* message = [[[[url query] componentsSeparatedByString: @"="] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // show our alert UIAlertView* av = [[UIAlertView alloc] initWithTitle: @"My Custom Title" message: message delegate: nil cancelButtonTitle: @"OK" otherButtonTitles: nil]; [av show]; return NO; } return YES; } 方法确实映射到真实的alert()。 (事实上​​确实如此!)其次,我们可以提出一些机制来识别来自其​​他应用程序源UIAlertView的{​​{1}}来源alert()。 (我们可以!)

我的方法是调动UIAlertView。我知道 - swizzling sucks and has all sorts of drawbacks。如果我能提供帮助,我不会在生产应用程序中徘徊。但对于这个科学项目,我们将调整UIAlertViews方法。

我发现1)UIAlertView将构建一个UIAlertView setDelegate:以显示javascript警报,以及2){UENlertView UIWebView之前设置UIAlertView标题已设定。通过使用我自己的方法调动UIAlertView,我可以完成两件事:1)我可以确定delegate代表UIAlertView setDelegate:进行委托(只需检查代表......) 2)我有机会在显示警报视图之前重新设置标题。

您可能会问“为什么不只是调动UIAlertView方法?”这会很棒,但在我的实验中我发现UIWebView从未调用过UIWebView。它必须调用其他一些内部方法,我没有进一步调查。

我的解决方案在UIAlertView上实现了一个类别,它添加了几个类方法。基本上,您使用这些方法注册UIWebView,并提供要使用的替换标题。或者,您可以提供一个回调块,在调用时返回标题。

我使用iOS6 UIAlertview -show类来保存一组UIWebView到标题的映射,其中UIWebView是一个弱键。这样我就不必取消注册我的show,一切都得到了很好的清理。 因此,此当前实现仅限iOS6。

以下是在基本视图控制器中使用的代码:

NSMapTable

解决方案3 :经过反思,这是一种比我最初在解决方案2中描述的更简单的技术。它仍然取决于未记录的事实,即javascript警报是使用其委托设置为的UIAlertView实现的采购UIWebView。对于这个解决方案,只需子类化UIWebView并为UIAlertView willPresentAlertView:实现自己的委托方法,并在调用它时,将标题重置为您想要的任何内容。

UIWebView

答案 2 :(得分:10)

不能在Javascript警报中执行此操作。

但是如果Javascript是你的,那么你可以改为调用Objective C并调用iOS本机警报,而不是调用警报。

如果Javascript不是您的,那么使用UIWebView您可以注入一些Javascript来覆盖默认行为并将其更改为调用iOS本机警报,例如类似

window.alert = function(message) {
  window.location = "myScheme://" + message"
};

然后在UIWebView的shouldStartLoadWithRequest中查找myScheme并解压缩消息

这是从Javascript调用Objective-C的标准方法

How to call Objective-C from Javascript?

答案 3 :(得分:4)

对于它的价值,Phonegap / Cordova提供navigator.notification.alert功能。它允许指定自定义标题。

答案 4 :(得分:1)

只需为您的UIWebView创建一个类,并在其中创建willPresentAlertView(alertView:UIAlertView)函数。之后设置alertView.title = "your fav title"并完成。

    import UIKit

class webviewClass: UIWebView {

func willPresentAlertView(alertView: UIAlertView) {


    alertView.title = "my custum title"
}

}

之后,当显示警告或确认并显示时,将显示您的自定义标题。

答案 5 :(得分:0)

关于@twk所写的内容,我只是覆盖了警报功能。适用于ios7。

function alert(words){
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", 'data:text/plain,');
document.documentElement.appendChild(iframe);
window.frames[0].window.alert(words);
iframe.parentNode.removeChild(iframe);
}

答案 6 :(得分:0)

使用cordova-plugin-dialogs。它允许创建原生对话框。

下面的代码将创建本机警报:

navigator.notification.alert(message, alertCallback, [title], [buttonName])