Javascript包含加载时带回调的函数

时间:2011-07-12 08:41:00

标签: javascript jquery

对于我的网站,我想在检测到某些元素时使用条件javascript加载。起初我只创建了一个新的脚本元素并将其附加到头部。当我这样做时,该语句后面的命令总是会失败,因为浏览器仍在加载javascript文件并且该函数尚未就绪。 $("element").something is not a function

第二个问题是我的脚本的另一部分想要包含之前已经请求过的脚本。我无法安全地假设脚本始终仍在加载或已经加载到该点。

所以我编写了一个脚本,可以在加载脚本/脚本时执行回调。这就是我现在的功能:

/* LOADING LIST */
var loading = new Array();

function include(script, callback) {
    if (script instanceof Array) {
        /* load an array of scripts */
        if (script.length > 1) {
            var top = script.shift();
            include(top, function() {
                include(script, callback);
            });
        } else
            include(script[0], callback);
    } else {
        var source = base_url + script;
        var type = /[^.]+$/.exec(script);

        if (type == "js") {
            if ($('script[src="' + source + '"]').length == 0) {
                /* first time script is requested */
                loading[script] = true;

                var e = document.createElement('script');
                e.src = source;
                e.type = "text/javascript";
                e.onload = function() {
                    delete loading[script];
                    if (callback !== undefined) {
                        callback();
                    }
                };
                document.getElementsByTagName("head")[0].appendChild(e);
            }
            else if(script in loading) {
                /* script is being loaded */
                var e = $('script[src="' + source + '"]')[0];
                var old = e.onload;
                e.onload = function() {
                    old();
                    callback();
                };
            }
            else {
                /* script is loaded */
                callback();
            }
        }
        else if (type == "css") {
            /* no need to wait for stylesheets */
            if ($('link[href="' + source + '"]').length == 0) {
                var e = document.createElement('link');
                e.rel = 'stylesheet';
                e.type = 'text/css';
                e.href = source;
                document.getElementsByTagName("head")[0].appendChild(e);
            }
            if (callback !== undefined) {
                callback();
            }
        }
    }
}

它支持这样的事情:

if($('.wysiwyg').length>0) {
    include(['javascript/ckeditor/ckeditor.js','javascript/ckeditor/adapters/jquery.js'], function() {
        $(".wysiwyg").ckeditor();
    }
}

这只会在加载所有提到的脚本时执行回调。

我不太了解javascript,我想知道这个脚本是否会变得更短和/或效率更高。

1 个答案:

答案 0 :(得分:1)

你应该使用jQuery中的$ .getScript()。它做你正在做的事情。您还可以使用$ .ajaxSetup({async:false});

加载它

例如

$.ajaxSetup({async: false});
$.getScript('myClass.js');
imFromMyClass();

我使用的函数如下:

function require(module) {
    $.ajaxSetup({async: false, cache: true});

    if (window['matchExtension'] === undefined) {
        window['matchExtension'] = function(filename, extensions) {
            return (getFileExtension(filename).match(new RegExp("(" + extensions + ")", "ig")));
        }
    }

    if (typeof module == 'string') {
        var tmp = "";
        if (matchExtension(module, "htm*") || matchExtension(module, "txt")) {
            tmp = $.get(module).responseText;
            return tmp;
        } else if (matchExtension(module, "css")) {
            var obj = $.get(module);
            if (obj.status == 404) return '';

            tmp = obj.responseText;
            var el = document.createElement('style');
            el.type = 'text/css';
            el.media = 'screen';
            document.getElementsByTagName('head')[0].appendChild(el);
            if(el.styleSheet) el.styleSheet.cssText = tmp;// IE method
            else el.appendChild(document.createTextNode(tmp));// others
        } else if (module.EndsWith("/")) {
            return $.get(module).responseText; // directory listing
        } else {
            $.getScript(module);
        }
    } else {
        $.ajaxSetup({async: false, cache:true});
        for (var i =0, len = module.length; i < len; i++) $.getScript(module[i]);
    }
    return true;
}

var content = require('someFile.html');
require('someStyle.css');
require('someClass.js');
require(['class1.js', 'class2.js', 'class3.js']);

加载javascript文件数组时可以做的另一项改进是将列表提供给在同一响应中将它们连接起来的服务器脚本