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

在iOS中更改JavaScript警报对话框标题,javascript,ios,uiwebview,Javascript,Ios,Uiwebview,是否可以在iPhone中更改UIWebview中的JavaScript警报标题?不,在JavaScript警报中不能这样做 但是如果Javascript是您的,那么您可以调用调用调用Objective C的函数并调用iOS本机警报,而不是调用警报 如果Javascript不是您的,那么您可以使用UIWebView注入一些Javascript来覆盖默认行为,并将其更改为调用iOS本机警报,例如 window.alert = function(message) { window.location

是否可以在iPhone中更改
UIWebview
中的JavaScript警报标题?

不,在JavaScript警报中不能这样做

但是如果Javascript是您的,那么您可以调用调用调用Objective C的函数并调用iOS本机警报,而不是调用警报

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

window.alert = function(message) {
  window.location = "myScheme://" + message"
};
然后在UIWebView的shouldStartLoadWithRequest中查找myScheme并提取消息

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


基本上您无法更改标题,但最近我找到了一种显示无标题警报对话框的方法

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);

无论如何,Phonegap/Cordova提供了一个功能。它允许指定自定义标题。

我为这个问题提供了三种不同的解决方案。生产代码的最佳解决方案是@Martin H所描述的解决方案。我唯一补充的是一个具体的示例,展示了如何实现它

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

解决方案1:下面是一个具体示例,演示了@Martin H提出的技术。这可能是最好的解决方案,因为它不依赖于
UIWebView
/
UIAlertView
未记录的行为

@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;
}
解决方案3:经过思考,这里有一种比我最初在解决方案2中描述的更简单的技术。这仍然取决于javascript警报是使用UIAlertView实现的这一未记录的事实,该UIAlertView的委托设置为源UIWebView。对于此解决方案,只需将UIWebView子类化并为UIAlertView willPresentAlertView:实现您自己的委托方法,当调用它时,将标题重置为您想要的任何内容

@interface TSWebView : UIWebView
@end

@implementation TSWebView

- (void) willPresentAlertView:(UIAlertView *)alertView
{
    if ( [self.superclass instancesRespondToSelector: @selector( willPresentAlertView:) ])
    {
        [super performSelector: @selector( willPresentAlertView:) withObject: alertView];
    }

    alertView.title = @"My Custom Title";
}

@end

@interface TSViewController () <UIWebViewDelegate>
@end

@implementation TSViewController

- (UIWebView*) webView
{
    return (UIWebView*) self.view;
}

- (void) loadView
{
    UIWebView* wv = [[TSWebView 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
{
    // trigger an alert
    [webView stringByEvaluatingJavaScriptFromString: @"alert('hello, world');" ];
}

@end
@interface TSWebView:UIWebView
@结束
@Web视图的实现
-(void)willPresentAlertView:(UIAlertView*)alertView
{
if([self.superclass instanceRespondtoSelector:@selector(willPresentAlertView:)]))
{
[超级性能选择器:@selector(willPresentAlertView:)with object:alertView];
}
alertView.title=@“我的自定义标题”;
}
@结束
@接口TSViewController()
@结束
@TSViewController的实现
-(UIWebView*)webView
{
返回(UIWebView*)self.view;
}
-(void)负荷视图
{
UIWebView*wv=[[TSWebView alloc]initWithFrame:CGRectMake(0,0320480)];
wv.delegate=self;
wv.scalesPageToFit=是;
self.view=wv;
}
-(无效)viewDidLoad
{
[超级视图下载];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@]http://www.craigslist.org"]]];
}
-(无效)webViewDidFinishLoad:(UIWebView*)webView
{
//触发警报
[webView stringByEvaluatingJavaScriptFromString:@“警报('hello,world');”;
}
@结束

与@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);
}

使用cordova插件对话框。它允许创建本机对话框

以下代码将创建本机警报:

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

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

    import UIKit

class webviewClass: UIWebView {

func willPresentAlertView(alertView: UIAlertView) {


    alertView.title = "my custum title"
}

}

之后,当任何时候发出警报或确认。。。如图所示,将显示您的自定义标题。

我想在ios中更改网页的javascript警报对话框标题。bij是什么?这是一个很好的问题,很难找到有关此主题的信息。如果你投了反对票,你能提供一些关于如何改进这个问题的信息吗?太棒了!谢谢。在ios safari浏览器中运行良好。。。不过在应用程序中不是很好。它在iOS 7中工作正常,但在iOS 8中它以粗体显示文本。知道吗?它在mozilla(41.0.2版)中抛出了“未捕获的异常:内存不足”。有什么想法吗?有时候,当“removeChild(iframe)”时,这会改变ios webview中div的顺序。从你的回答中,我知道你非常精通Objective-C。我真的不知道你是否使用过web视图,但如果你这样做,如果你能写一个简洁的例子,说明Cordova/Phonegap用来搭建JS到Objective-C之间的桥梁的技术,你不觉得它会更有用吗?我确信他们使用的技术之一是Javascript中的
window.location
,并观察Objective-C中webview位置的变化,读取URL中嵌入的参数。然后取消导航。我知道这个技巧,但我不能写出有意义的Objective-C。我说的原因是,现在你有了一个答案,你自己说你不会使用它。Phonegap技术被广泛应用,所以它可能是一个合理的解决方案。@MerynStol-好的,你知道了。我为window.location技术添加了一个简洁的示例。也是我的原始解决方案的一个更简单的变体。非常有用!你应该得到赏金。UIWebView的子类看起来也很吸引人。@TomSwift解决方案1适用于alert()函数,但不适用于位置权限alert!!!。不建议使用解决方案2。解决方案3不起作用,我可以获得标题,但更改alertView的标题似乎没有效果
    import UIKit

class webviewClass: UIWebView {

func willPresentAlertView(alertView: UIAlertView) {


    alertView.title = "my custum title"
}

}