2010-08-18 1 views
6

Ich versuche, einige JS vor dem OnLoad Ereignis der Seite ausgelöst wird.JavaScript Fehler in UIWebView Callback "Start laden"

Aber ich habe Probleme beim erfolgreichen Aufruf stringByEvaluatingJavaScriptFromString in der webViewDidStartLoad Delegate-Methode.

Um das Problem zu reproduzieren, können Sie den folgenden Code verwenden.

Delegierter Umsetzung:

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

ansehen 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> 

Diese Seite auf den ersten Blick funktioniert ("Alles in Ordnung"), aber nicht auf alle neu geladen, unabhängig von der Reload-Methode. Wie Sie wahrscheinlich erwarten würden, funktioniert dies auch nicht in dem Delegaten shouldStartLoadWithRequest.

Ich habe auch versucht, das Javascript sofort nach webViewDidStartLoad mit performSelector:withObject:afterDelay:0, vergeblich.

Irgendwelche Ideen?

+0

Irgendeine Lösung dafür? – Tudorizer

+0

Ja, siehe meinen Kommentar unten. –

Antwort

1

Ich konnte es eine NSTimer mit funktioniert

- (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"]; 
    } 
} 
+0

Ich weiß es zu schätzen, dass Sie sich die Zeit genommen haben, zu antworten, Chris. Dies sieht jedoch nicht wie eine Lösung aus. Es sei denn, der Server benötigt eine sehr lange Zeit, um darauf zu reagieren. Die Wahrscheinlichkeit ist groß, dass dieser Timer bei Bedarf nicht ausgelöst wird. Ich suche wirklich nach einer deterministischen Lösung, die nicht von Timern abhängig ist. –

+0

Das funktioniert übrigens mit einem Intervall von 0. Aber es ist besser, den Timer in webViewDidStartLoad zu erstellen und ihn sowohl in webViewDidStartLoad als auch in webViewDidEndLoad ungültig zu machen, als ihn immer laufen zu lassen. Dies scheint auch die Theorie zu unterstützen, dass webViewDidStartLoad vor einer Aufräumoperation aufgerufen wird, und das Fensterobjekt wird entstellt, bevor der Webframe für die nächste Seitensicht eingerichtet wird. –

0

Sie müssen etwas tun, wie folgt aus:

Delegierter Umsetzung:

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

Html-Datei:

<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> 
+0

Dies würde den Inhalt der Webansicht tatsächlich neu schreiben. Ich suchte nach einer Möglichkeit, die Seite so auszutricksen, dass sie dachte, sie hätte Flash, indem ich das Fensterobjekt manipulierte, bevor die Ansicht irgendeinen Code ausführte. –