Alright, I've been working on this kind of stuff quite intensively a
while back. The good news is, all major browsers (ie 6, ff 1.5+, opera
9) can include JS on the fly and trigger a callback function after that
is done. In your case you would only need to modify your plugin like this:
------------------------------------------------------------------------------------------------------------
(function(jq){
jq.extend({
require: function(plugin, o){
o = jq.extend({
css: false,
jsbase: '',
cssbase: '',
onLoad: null
wait: true
}, o || {});
var src = o.jsbase + '/' + plugin + '.js';
// Provide a callback function to the getScript function
jq.getScript(src, o.onLoad);
if(o.css){
var c = document.createElement('link');
c.type = 'text/css';
c.rel = 'stylesheet';
c.href = o.cssbase + '/' + plugin + '.css';
jq('head')[0].appendChild(c);
}
}
});
})(jQuery);
// And here is how to use it
$(document).ready(function()
{
jQuery.require('jquery.accordion',
{
onLoad: function()
{
$('#myaccordion').Accordion();
}
});
}
------------------------------------------------------------------------------------------------------------
The bad news is: Your JS will be included *after* the DOM has loaded
which destroys the awesomeness that comes with the jQuery.fn.ready
function. Now I've been banging my head against this for hours and my
basic conclusion is this:
* In FF >= 1.5 it is possible to dynamically include JS files before
the DOM finishes loading (just like if they were included in
<head>) and get a callback for each one when it has loaded
* In IE >= 6 this is possible as well, however you only get a
callback when *all* dynamically included JS files have finished
loading and after that you loose the ability to include additional
files in the callback function. Another thing is that IE seems to
trigger the callbacks in random order, so you need to synchronize
them when they come in manually.
Here is a demo of the best method I was able to develop:
http://demos.thinkingphp.org/dynamic_js_including/
Try it in FF (with Firebug installed) and then IE 6 and you'll see what
kind of problem there is. I've not cleaned up this code at all, but I
hope you can understand it anyway:
http://demos.thinkingphp.org/dynamic_js_including/js/script_includer.js
Now you could try synchronous ajax to load the script, but that would
freeze the browser so I did not work on that. What I ended up doing was
to move the logic for JS inclusion in the php code of my application.
But if you only need to include/require other JS files once at the
beginning and not in the callback functions for inclusions, then you
should be able to use my method.
I wish I had more time to explain the things I've tried out and the
problems with them in IE 6, but I've already spent way too much time on
this, so let me just warn you that it'll be very difficult to make a
semi-asynchronous JS require function (one that loads before the DOM,
but does this asynchronously and triggers a callback, just like
<script>'s in <head> do on default).
-- Felix Geisendörfer aka the_undefined
--------------------------
http://www.thinkingphp.org
http://www.fg-webdesign.de
Jip wrote:
Hello all, this is my first posting, although I've been watching you for some
time :)
I'm trying to develope a small piece for dynamic loading in jquery, wich
loads the .js and .css source files on the fly without any special markup in
the html page. Probably you've seen this before (dojo.require and siimilar)
The problem is that it seems that the browser doesn't wait until the script
(the plugin) is finished loading, and give errors when I try to use it.
For example, in $(document).ready( ...
jQuery.require('jquery.accordion');
$('#myaccordion').Accordion();
gives an error, but later, if I try the 2nd line in firebug, the plugin
works as expected. I've tried in Firefox 2 and IE7 with same results. I know
that is a problem with the synchronism, but I don't know how to resolve it.
here is the code:
(function(jq){
jq.extend({
require: function(plugin, o){
o = jq.extend({
css: false,
jsbase: '',
cssbase: '',
wait: true
}, o || {});
var src = o.jsbase + '/' + plugin + '.js';
jq.getScript(src);
// here it should wait, but how?
if(o.css){
var c = document.createElement('link');
c.type = 'text/css';
c.rel = 'stylesheet';
c.href = o.cssbase + '/' + plugin + '.css';
jq('head')[0].appendChild(c);
}
}
});
})(jQuery);
Any ideas?
Thanks in advance.
Jip
_______________________________________________
jQuery mailing list
[email protected]
http://jquery.com/discuss/