Javascript包含函数与回调时加载

Javascript include function with callback when loaded

本文关键字:加载 回调 包含 函数 Javascript      更新时间:2023-09-26

对于我的网站,我想在检测到某些元素时使用条件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,我想知道这个脚本是否可以变得更短和/或更高效。

你应该使用jQuery中的$. getscript()。它会做你正在做的事情。你也可以让它与$同步加载。ajaxSetup({异步:假});

例如

$.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文件数组时,你可以做的另一个改进是将列表提供给服务器脚本,该脚本将它们全部连接到同一个响应