Adding new elements to a WebFrame's DOM from Cocoa/Objective-C
I am working on a project that uses a WebView to display the majority of its content. Content is loaded from HTML files on disk that I didn't write and have no control over. I want to be able to apply a custom CSS style to every page that is loaded into the view. To do that, I've implemented the following snippet in -(void)webView:didFinishLoadForFrame:
DOMDocument *doc = [frame DOMDocument];
DOMElement *link = [doc createElement:@"link"];
[link setAttribute:@"rel" v开发者_如何转开发alue:@"stylesheet"];
[link setAttribute:@"type" value:@"text/css"];
[link setAttribute:@"href" value:[cssPath path]];
DOMNodeList *heads = [doc getElementsByName:@"head"];
[[heads item:0] appendChild:link];
I've tried the same sequence of statements in a JavaScript file (in JavaScript, not Objective-C of course) and it has worked. The above code, however, doesn't work. I've stepped through it with the Xcode debugger, and it looks like everything is working (variables initialized properly with valid data, etc) but I don't see a change in the frame. What am I doing wrong? Is there a better way to go about what I'm trying to accomplish? Is there a reason it would work in JavaScript but not Objective-C?
Edit: I've been playing around with this over the past couple days. I still haven't been able to use the DOM* objects, but I have gotten some results doing this:
NSString *js = @"var link = document.createElement('link');";
js = [js stringByAppendingString:@"link.setAttribute('rel', 'stylesheet');"];
js = [js stringByAppendingString:@"link.setAttribute('type', 'text/css');"];
js = [js stringByAppendingFormat:@"link.setAttribute('href', '%@');",
[defaultCSSURL path]];
js = [js stringByAppendingString:
@"document.getElementsByTagName('head')[0].appendChild(link);"];
[[view windowScriptObject] evaluateWebScript:js];
I'm not particularly happy with this solution, but it's the only way I've been able to make it work. Note that defaultCSSURL
is a static NSURL pointing to a CSS file in the project.
I'm not sure why this particular example fails, but I've accomplished this by using the script object to execute javascript on the page (and jquery because it's so convenient):
[scriptobj evaluateWebScript:@"$('#my_div').append('my text');"];
The script object can be obtained by setting the object as the webview delegate (webView:windowScriptObjectAvailable
)
But that's just one approach. I know I had a ton of trouble dealing with the DOMDocument object itself.
精彩评论