webkit - listener fails on second page load
I have a Mac client application written in Objective-C that presents the user with a list of html documents in a table, and when the user clicks on a row it loads the selected HTML page into a WebView.
Every HTML page has a listener on "click" that calls an Objective-C method.
When the application runs and the user clicks on the first row, everything works fine. The "click" event is trapped, and my Objective-C method is successfully called.
However, when the user clicks on a second (or subsequent) record and then a new HTML page is loaded in to the same WebView the listener on "click" never fires.
If the selected record is the first to be loaded it always works fine, so the problem is not one of bad HTML files. FYI, all files are largely identical.
I've boiled 开发者_如何学运维the problem down in a simple test application. It can be downloaded here - http://dl.dropbox.com/u/160638/Work/TCL/MapTest2.zip
NOTE: The test application outputs a message to the standard log, so you will need to check either the log window in Xcode or Console.app to see the Objective-C method call working (or not). The buttons along the top are in pairs, loading first from a local file, then an HTML page as a string, then pulling an HTML page from a web site.
From extensive searching I'm guessing that when I load the second HTML page into the WebView the previous page is retained somehow, and the two listeners on "click" are clashing in some way? Is that possible?
Can anyone recommend a way to load HTML pages such that subsequent loads will work? Is there a way to ensure that any pages previously loaded into a WebView are fully unloaded before I load the second page?
Any suggestions you could make would be appreciated.
Regards
Darren.
The problem is that windowScriptObject
is unique to each HTML document. You need to perform
[[[self mapView] windowScriptObject] setValue:self forKey:@"AppDelegate"];
each time the html is loaded. Also, note that windowScriptObject
is not immediately available after calling loadHTMLString:baseURL:
. It's only done when the HTML is ready. So, doing
[[[self mapView] mainFrame] loadHTMLString:htmlString baseURL:nil];
[[[self mapView] windowScriptObject] setValue:self forKey:@"AppDelegate"];
will not solve the problem. Rather, you should set up the windowScriptObject
in some delegate method of the view, after the loading is complete.
Now, give me part of your salary. (Joking :p)
Thanks to Yuji for the right answer.
The delegate method is:
-webView:didClearWindowObject:forFrame:
For example:
- (void) webView:(WebView *)sender
didClearWindowObject:(WebScriptObject *)windowObject
forFrame:(WebFrame *)frame
{
[windowObject setValue:self forKey:@"AppDelegate"];
}
This example was kindly given to me by another poster elsewhere, so thanks to him also.
精彩评论