I have no idea if this possible solution to making getScript work
across all browsers (including Safari) has already been mentioned, but
I thought I'd provide it in case anyone was looking for a way. I've
seen uses of timeouts and such to try to figure out when a script has
been loaded, but ultimately I think this solution is better. It gets
javascript (and css) by means of AJAX, then dynamically creates style
and script tags and appends the text content of the ajax response. Of
course a few browser specific fixes are incorporated, but that's the
gist of it. I made this plugin for personal use a couple months ago,
and I guess I should have probably shared it back then, but I hope
better late than never.

An example use of this plugin would be:

$("#load").click(function(){
        $.include("jqModal.css,jqModal.js,jqDnR-R.js", {onload: function(){
                $('<div class="jqmWindow"><div><h3 
style="cursor:move">Success!</
h3><hr /><p>If you\'re reading this message then the test was
successful...</p><p>You should be able to drag this box by its title.</
p><input type="button" value="Close" class="jqmClose" /></div></
div>').appendTo("body").jqm().jqDrag('h3').jqmShow().jqmAddClose('.jqmClose');
        }});
});

This uses $.include to dynamically load each listed file one after the
other. It might be beneficial because it doesn't load the script for
making jqModal work until it's needed. This might not be the best
example, but it shows what it can do.


/*
 * jQuery.include - A dynamic javascript/css loader plugin for jQuery.
 *
 * Copyright (c) 2007 Dave Stewart <[EMAIL PROTECTED]>, 
http://www.yesterdave.com
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * $Version: 2007.04.27 +r3
 *
 * hard time figuring out a way to ensure js/css is loaded before
proceeding with the next file
 *   - use ajax to get js/css file then inject it in a new script/
style tag
 *
 * hard time trying to figure out why safari wouldn't work with
either:
 *   - script.onload
 *   - script.text
 * finally found http://tobielangel.com/2007/2/23/to-eval-or-not-to-eval
 *   - append javscript text to script tag with
document.createTextNode
 *
 * keep in mind that no two external files should have the same name,
becase path is disregarded
 *
 * Options:
 *   - sync: determines whether or not the files are load
synchronously (Default: true)
 *   - onload: the function to run after all the files are loaded
(Default: null)
 *   - jsBase: the base directory where javascript files are found
(Default: '')
 *   - cssBase: the base directory where css files are found (Default:
'')
 *
 */
(function($){
        var list = {};
        var queue = [];
        var running = false;
        var add = function(file, o){
                o = $.extend({sync: true, onload: null, jsBase: '', cssBase: 
''}, o
|| {});
                fillList();
                var files = file.split(',');
                var len = files.length;
                $.each(files, function(i, file){
                        file = (file.indexOf('.css') > -1 ? o.cssBase : 
o.jsBase) + file;
                        var cb = (i == len - 1) ? o.onload : null;
                        if (!o.sync)
                                insert(file, cb || function(){}, false);
                        else
                                queue.push({file: file, onload: cb});
                });
                if (!running)
                        next();
        };
        var next = function(){
                if (queue.length > 0) {
                        running = true;
                        var item = queue.shift();
                        var cb = function(){
                                if (item.onload)
                                        item.onload();
                                next();
                        };
                        insert(item.file, cb, true);
                } else
                        running = false;
        };
        var insert = function(file, cb, sync){
                if (!list[file]) {
                        list[file] = true;
                        if (file.indexOf('.css') > -1)
                                createCSS(file, cb, sync);
                        else
                            createJS(file, cb, sync);
                } else
                        cb();
        };
        var createJS = function(file, cb, sync){
                if (!sync) {
                    $(document.createElement('script')).attr({type: 'text/
javascript', src: file}).appendTo('head');
                    cb();
                } else {
                $.get(file, null, function(jsText){
                var s = $
(document.createElement('script')).attr('type', 'text/javascript');
                if ($.browser.safari)
                    s.append(document.createTextNode(jsText));
                else
                    s[0].text = jsText;
                s.appendTo('head');
                cb();
                });
                }
        }
        var createCSS = function(file, cb, sync){
                if (!sync) {
                    $(document.createElement('link')).attr({type: 'text/css', 
rel:
'stylesheet', href: file}).appendTo('head');
                    cb();
                } else {
                    $.get(file, null, function(cssText){
                if ($.browser.msie) {
                    var s = document.createStyleSheet();
                    s.cssText = cssText;
                } else {
                    var s = $
(document.createElement('style')).attr('type', 'text/css');
                    try {
                        s.append(document.createTextNode(cssText));
                    } catch (e) {
                        s[0].cssText = cssText;
                    }
                    s.appendTo('head');
                }
                cb();
                    });
                }
        };
        var fillList = function(){
                var toAdd = [];
                $("script").each(function(){
                        toAdd.push(this.src);
                });
                $("link").each(function(){
                        toAdd.push(this.href);
                });
                $.each(toAdd, function(i, file){
                        if (file && file.length > 0 && file != '//:')
                                list[stripPath(file)] = true;
                });
        };
        var stripPath = function(href){
                return href.substring(href.lastIndexOf('/') + 1);
        };
        $.extend({
                include: add,
                externalResources: list
        });
        $(fillList);
})(jQuery);

Reply via email to