5

I am trying to inject JQuery into a UIWebView of a page that I can't control, say Google, for example. When a UITextField gets focus, I am executing the following lines of code:

NSString* scriptInject = @"var headElement = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); 
    script.setAttribute('src','http://jquery.com/src/jquery-latest.js');
    script.setAttribute('type','text/javascript'); headElement.appendChild(script);";
    [myWebView stringByEvaluatingJavaScriptFromString:scriptInject];    
    [myWebView stringByEvaluatingJavaScriptFromString:@"$(document).ready(function() {$('body').css('background', '#FF0000');}"];

I am executing the background change to validate that I am able to run a JQuery script. I can verify that the Objective-C method is being called, and I even planted an alert for the onload of the newly created <script> tag, so I know that it is being executed in the UIWebView. How do I inject it correctly that I can execute it?

EDIT:

I have event tried this after calling the function to change the color:

[myWebView stringByEvaluatingJavaScriptFromString:@"alert($('body').css());"];

No alert shows.

Wayne Hartman
  • 18,369
  • 7
  • 84
  • 116

2 Answers2

7

This has worked for me:

NSString *jqueryCDN = @"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
NSData *jquery = [NSData dataWithContentsOfURL:[NSURL URLWithString:jqueryCDN]];
NSString *jqueryString = [[NSMutableString alloc] initWithData:jquery encoding:NSUTF8StringEncoding];
[webView stringByEvaluatingJavaScriptFromString:jqueryString];

[webView stringByEvaluatingJavaScriptFromString:/*jquery commands here*/];

Taken from this article.

Stunner
  • 12,025
  • 12
  • 86
  • 145
  • I know this is an old thread, but both this code and the code in the source article make poor use of dataWithContentsOfURL:. The jQuery library ends up being downloaded from googleapis.com while blocking the main thread. – Richard Venable Apr 01 '14 at 02:46
  • Agreed! This answer is here for demonstration purposes only, this isn't the recommended approach, of course. – Stunner Apr 01 '14 at 03:22
  • when should i implement "stringByEvaluatingJavaScriptFromString"? didFinish? – Carl Hung Jul 04 '20 at 16:49
4

If jQuery is not in the DOM already you can use stringByEvaluatingJavaScriptFromString: to inject it. I've had similar problem, I wrote a blog post about it: HTML parsing/screen scraping in iOS.

Benedict Cohen
  • 11,912
  • 7
  • 55
  • 67
  • 1
    I find that my code does indeed work, just not reliably. After reading your article, it may be because the DOM is not yet ready. After skimming over your article, performing a delayed selector may be the trick for waiting to execute the change using jQuery until the DOM is ready. I'll give it a try when I get a chance. – Wayne Hartman Aug 26 '10 at 00:32
  • your blogpost disappeared from the web :( – Lior Frenkel Mar 10 '11 at 05:54
  • @Hamutsi. Fixed! I changed blog engine and broke all my links. – Benedict Cohen Mar 10 '11 at 18:19
  • your blog has again disappeared, guess this is why SO always want you to copy code into answers – lewis Aug 29 '16 at 16:08
  • Your blog is gone again; post the answer here instead :) no one can see the solution now – Gerald Eersteling May 16 '19 at 13:21