Ed McManus
Ed McManus

Reputation: 7076

JavaScript Broken in UIWebView's "Start Load" Callback

I'm trying to execute some JS before the page's onLoad event fires.

But I'm having trouble successfully calling stringByEvaluatingJavaScriptFromString in the webViewDidStartLoad delegate method.

To reproduce the issue, you can use the following code.

Delegate implementation:

-(void)webViewDidStartLoad:(UIWebView *)webView {
    [webView stringByEvaluatingJavaScriptFromString:@"window.valueHasBeenSet=true"];
}

View this HTML:

<html>
<head></head>
<body>

<script type="text/javascript" charset="utf-8">
    if (window.valueHasBeenSet)
    {
        // We enter this branch the first time
        document.write('<h3>Everything is OK. Value has been set.</h3>');
    }
    else
    {
        // We incorrectly enter this branch on reloads
        document.write('<h3>Error. Value has not been set.</h3>');
    }
</script>

<a href="javascript:window.location.reload()">Reload</a>

</body>
</html>

This page works on the first view ("Everything is OK.") but fails on all reloads, regardless of the reload method. As you'd probably expect, this doesn't work in the shouldStartLoadWithRequest delegate, either.

I also tried executing the javascript immediately following webViewDidStartLoad with performSelector:withObject:afterDelay:0, to no avail.

Any ideas?

Upvotes: 6

Views: 1840

Answers (2)

chris
chris

Reputation: 11

I managed to make it work using a NSTimer

- (void)viewDidLoad {
    timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(update) userInfo:nil repeats:YES];
}

-(void)update{
    if (Progress.progress <= 1.0) {
        [website stringByEvaluatingJavaScriptFromString:@"window.valueHasBeenSet=true"];
    }
}

Upvotes: 1

Sylter
Sylter

Reputation: 1623

You have to do something like this:

Delegate implementation:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSLog(@"webViewDidFinishLoad");
    [webView stringByEvaluatingJavaScriptFromString:@"foo(true);"];
}

.html file:

<html>
<head></head>

<script type="text/javascript" charset="utf-8">
function foo (value) {
    if (value)
    {
        // We enter this branch the first time
        document.write('<h3>Everything is OK. Value has been set.</h3>');
    }
    else
    {
        // We incorrectly enter this branch on reloads
        document.write('<h3>Error. Value has not been set.</h3>');
    }

    document.write('<a href="javascript:window.location.reload();">Reload</a>');
}
</script>
<body>



</body>
</html>

Upvotes: 0

Related Questions