Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Incremental code loading under AJAX

Status
Not open for further replies.

dkm666

Programmer
Feb 26, 2008
15
US
I have built several projects now using AJAX to load page fragments instead of whole pages, and am pretty pleased with how this all works. I have come to the point where I wanted to avoid having to load all the JavaScript files for all possible parts of the application upon a first visit by a new user, so I came up with a scheme for loading functions only when they relate to a particular page fragment.

Essentially, I enclose the code to be downloaded in XML tags (a CDATA block), check whether the stuff has been loaded before, and if not, eval() the string of code. This works, with one caveat: instead of writing "function foo()", I have to write "foo = function ()", so that the function definition persists beyond the lifetime of the routine that accepts the download.

All this is fine, but I have not found a way to make code downloaded in this way visible to the Firebug run-time environment. This makes debugging pretty tough.

Any suggestions as to what I need to do to achieve the holy grail: code downloaded with the HTML that uses it, rather than needing to be loaded at the beginning of the application?

 
Why not create the script element dynamically, having the script load normally, instead of using AJAX to return it? That way you'll get whatever scope you want, and Firebug will be able to see the script:

Code:
var theScript = document.createElement('script');
theScript.type = 'text/javascript';
theScript.src = '[URL unfurl="true"]http://what.ever.com/your/script/file.js';[/URL]
document.getElementsByTagName('head')[0].appendChild(theScript);

Hope this helps,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Thanks; this is elegant -- getting the browser to do the work. I'll try it out on all the browsers in my testing stable tonight.
 
Well, I finally got time free to do the experiment you suggested, and I have mixed results to report: creating the script element, assigning a URL to the .src property and attaching the element to the document head DOES cause Firefox to download the indicated script file, and DOES make the downloaded javascript visible to Firebug.

HOWEVER, the functions downloaded are not put into the symbol table, as evidenced by my getting an error as soon as I try to invoke any of the functions downloaded (through elements that came down along in the same AJAX request).

I even asked Firebug to WATCH one of the function names, and it tells me that variable is undefined, even though I can look at the script file in the left-hand window and see the text of the function.

Ideas?
 
Yes, I thought about that problem, too. The exact sequence is:
1. XML arrives
2. If it contains a JavaScript library tag, extract the filepath, construct the script element, and start that download.
3. Stuff HTML (containing references to this JavaScript) into target DIV (using innerHTML).
4. If there is JavaScript that must be executed on every download, eval that script fragment.

Somewhere within this try/catch block, I get an exception -- "ReferenceError: ckLogin is not defined", even when I refresh the page (and so the code is already present).

Further, if I ask Firebug to display the value of ckLogin, via the "watch" field, I get the error "ckLogin is not defined" there, too.

Do I need to wait for the JavaScript download to complete *before* I insert the HTML into its DIV ?

BTW, many thanks for pursuing this with me. If I can get it to work right, this will be really slick.
 
Is ckLogin defined as a global in the external JS file, or do you have to run some code to set it? It's odd that Firebug isn't showing it up after a delay, though...

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
I worked some more on this tonight, and must sheepishly report that my previous post is in error: if I stop Firebug at a breakpoint, apparently that also halts any javascript activity toward loading scripts, and that seems to be what was producing the results I reported yesterday.

I improved my library routines some more today, including a scheme to check if an AJAX-requested .js file was already loaded, and to defer eval()ing a second block of javascript until the file had loaded. I am happy to report that this all works fine in Firefox 2.0.0.12, Safari 3.0.4 (for windows), and, after some more tweaking, in IE 7.0.5730.13. The extra tweak for IE had to do with the fact that IE doesn't actually fire an onload event when the script is all there; instead, it fires an onreadystatechange event, which I checked for "complete" or "loaded", per several postings on the web.

So the final result is that, for all these browsers, I can put one line into an XML response: <jssrc>filepath</jssrc>, and cause the corresponding file of javascript to be downloaded at the time it is about to be needed. Then, a second XML item can specify code to be executed as a consequence of the AJAX request. This code block is eval()ed either immediately on receipt (if the support files are there already), or when the javascript load is complete.

Thanks for all your help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top