在JS中动态加载JS

Rij*_*hna 290 javascript jquery

我有一个动态网页,我需要IF在另一个javascript文件中导入一个外部JS文件(在一个条件下).

我试图寻找一个可行的解决方案,但它没有用.

我已经尝试使用JS文件加载到DOM,document.createElement()但它也没有用.显然,Js已加载到DOM中,但在当前的JS文件中无法访问.

jQuery中的解决方案也没问题

Zir*_*rak 534

我的猜测是,在你的DOM解决方案中你做了类似的事情:

var script = document.createElement('script');
script.src = something;
//do stuff with the script
Run Code Online (Sandbox Code Playgroud)

首先,这不起作用,因为脚本没有添加到文档树中,因此不会加载它.此外,即使你这样做,在加载另一个脚本时也会继续执行javascript,因此在完全加载该脚本之前,它的内容将无法使用.

您可以收听脚本的load事件,并按照您的意愿处理结果.所以:

var script = document.createElement('script');
script.onload = function () {
    //do stuff with the script
};
script.src = something;

document.head.appendChild(script); //or something of the likes
Run Code Online (Sandbox Code Playgroud)

  • 确保在`onload`属性之后设置`src`属性[来源](http://stackoverflow.com/a/16231055/1852456) (45认同)
  • 没有必要过分复杂的事情.布拉沃 (12认同)
  • 这应该是最好的答案,不需要使用jQuery来完成这样的简单任务! (12认同)
  • @ woojoo666为什么在`onload`之后?是不是只在`appendchild`之前设置`src`了? (7认同)
  • @AliSharabiani oops你是对的,只有元素已经在页面上才有意义.根据我的经验,在设置`src`之前首先在页面上有元素是比较常见的,主要是你要动态地改变*src`的所有情况的bc,比如`img`标签等等.所以我认为更好的做法是习惯在`onload`之后放置`src` (4认同)
  • @YevgeniyAfanasyev:不要用 async/defer 标记动态加载的脚本。由于您是动态加载脚本,因此何时加载脚本的决定已经在您自己的控制之下。 (2认同)

kay*_*yen 136

jQuery $.getScript()有时会出错,所以我使用自己的实现,如:

jQuery.loadScript = function (url, callback) {
    jQuery.ajax({
        url: url,
        dataType: 'script',
        success: callback,
        async: true
    });
}
Run Code Online (Sandbox Code Playgroud)

并使用它像:

if (typeof someObject == 'undefined') $.loadScript('url_to_someScript.js', function(){
    //Stuff to do after someScript has loaded
});
Run Code Online (Sandbox Code Playgroud)

  • 你可以提供一些关于它何时出错的信息? (64认同)
  • 我调整你的脚本只是稍微让它执行如果加载否则加载然后执行... jQuery.pluginSafe = function(name,url,callback){if(jQuery [name]){callback; } else {jQuery.ajax({...}); }} (3认同)
  • 它并不理想,因为加载的文件未在DevTools的Sources中显示.这是因为这个文件是'eval`ed (3认同)
  • 我不想使用 JQuery。有没有纯JS的方式? (3认同)
  • 另一个问题是,这将吞噬所有语法错误。因此,您可能想在`fail()`中捕获它们。 (2认同)

小智 72

我需要经常这样做,所以我使用这个:

var loadJS = function(url, implementationCode, location){
    //url is URL of external file, implementationCode is the code
    //to be called from the file, location is the location to 
    //insert the <script> element

    var scriptTag = document.createElement('script');
    scriptTag.src = url;

    scriptTag.onload = implementationCode;
    scriptTag.onreadystatechange = implementationCode;

    location.appendChild(scriptTag);
};
var yourCodeToBeCalled = function(){
//your code goes here
}
loadJS('yourcode.js', yourCodeToBeCalled, document.body);
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此站点如何在另一个JavaScript文件中包含JavaScript文件?,这是我的功能理念的来源.

  • 支持包含“onload”。 (2认同)

mut*_*thu 25

您可以动态加载页面内的js而不是另一个js文件

你必须使用getScript来加载js文件

$.getScript("ajax/test.js", function(data, textStatus, jqxhr) {
console.log(data); //data returned
console.log(textStatus); //success
console.log(jqxhr.status); //200
console.log('Load was performed.');
});
Run Code Online (Sandbox Code Playgroud)

  • 我不喜欢使用 jQuery。我需要用普通的旧 JS 来做这件事 (2认同)

Ste*_*ger 14

Necromaning.

我用它来加载依赖脚本;
它适用于IE8 +而不添加任何依赖于另一个库,如jQuery!

var cScriptLoader = (function ()
{
    function cScriptLoader(files)
    {
        var _this = this;
        this.log = function (t)
        {
            console.log("ScriptLoader: " + t);
        };
        this.withNoCache = function (filename)
        {
            if (filename.indexOf("?") === -1)
                filename += "?no_cache=" + new Date().getTime();
            else
                filename += "&no_cache=" + new Date().getTime();
            return filename;
        };
        this.loadStyle = function (filename)
        {
            // HTMLLinkElement
            var link = document.createElement("link");
            link.rel = "stylesheet";
            link.type = "text/css";
            link.href = _this.withNoCache(filename);
            _this.log('Loading style ' + filename);
            link.onload = function ()
            {
                _this.log('Loaded style "' + filename + '".');
            };
            link.onerror = function ()
            {
                _this.log('Error loading style "' + filename + '".');
            };
            _this.m_head.appendChild(link);
        };
        this.loadScript = function (i)
        {
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = _this.withNoCache(_this.m_js_files[i]);
            var loadNextScript = function ()
            {
                if (i + 1 < _this.m_js_files.length)
                {
                    _this.loadScript(i + 1);
                }
            };
            script.onload = function ()
            {
                _this.log('Loaded script "' + _this.m_js_files[i] + '".');
                loadNextScript();
            };
            script.onerror = function ()
            {
                _this.log('Error loading script "' + _this.m_js_files[i] + '".');
                loadNextScript();
            };
            _this.log('Loading script "' + _this.m_js_files[i] + '".');
            _this.m_head.appendChild(script);
        };
        this.loadFiles = function ()
        {
            // this.log(this.m_css_files);
            // this.log(this.m_js_files);
            for (var i = 0; i < _this.m_css_files.length; ++i)
                _this.loadStyle(_this.m_css_files[i]);
            _this.loadScript(0);
        };
        this.m_js_files = [];
        this.m_css_files = [];
        this.m_head = document.getElementsByTagName("head")[0];
        // this.m_head = document.head; // IE9+ only
        function endsWith(str, suffix)
        {
            if (str === null || suffix === null)
                return false;
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }
        for (var i = 0; i < files.length; ++i)
        {
            if (endsWith(files[i], ".css"))
            {
                this.m_css_files.push(files[i]);
            }
            else if (endsWith(files[i], ".js"))
            {
                this.m_js_files.push(files[i]);
            }
            else
                this.log('Error unknown filetype "' + files[i] + '".');
        }
    }
    return cScriptLoader;
})();
var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();
Run Code Online (Sandbox Code Playgroud)

如果您对用于创建它的typescript -version 感兴趣:

class cScriptLoader {
    private m_js_files: string[];
    private m_css_files: string[];
    private m_head:HTMLHeadElement;

    private log = (t:any) =>
    {
        console.log("ScriptLoader: " + t);
    }


    constructor(files: string[]) {
        this.m_js_files = [];
        this.m_css_files = [];
        this.m_head = document.getElementsByTagName("head")[0];
        // this.m_head = document.head; // IE9+ only


        function endsWith(str:string, suffix:string):boolean 
        {
            if(str === null || suffix === null)
                return false;

            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }


        for(var i:number = 0; i < files.length; ++i) 
        {
            if(endsWith(files[i], ".css"))
            {
                this.m_css_files.push(files[i]);
            }
            else if(endsWith(files[i], ".js"))
            {
                this.m_js_files.push(files[i]);
            }
            else
                this.log('Error unknown filetype "' + files[i] +'".');
        }

    }


    public withNoCache = (filename:string):string =>
    {
        if(filename.indexOf("?") === -1)
            filename += "?no_cache=" + new Date().getTime();
        else
            filename += "&no_cache=" + new Date().getTime();

        return filename;    
    }


    public loadStyle = (filename:string) =>
    {
        // HTMLLinkElement
        var link = document.createElement("link");
        link.rel = "stylesheet";
        link.type = "text/css";
        link.href = this.withNoCache(filename);

        this.log('Loading style ' + filename);
        link.onload = () =>
        {
            this.log('Loaded style "' + filename + '".');

        };

        link.onerror = () =>
        {
            this.log('Error loading style "' + filename + '".');
        };

        this.m_head.appendChild(link);
    }


    public loadScript = (i:number) => 
    {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = this.withNoCache(this.m_js_files[i]);

        var loadNextScript = () => 
        {
            if (i + 1 < this.m_js_files.length)
            {
                this.loadScript(i + 1);
            }
        }

        script.onload = () =>
        {
            this.log('Loaded script "' + this.m_js_files[i] + '".');
            loadNextScript();
        };


        script.onerror = () =>
        {
            this.log('Error loading script "' + this.m_js_files[i] + '".');
            loadNextScript();
        };


        this.log('Loading script "' + this.m_js_files[i] + '".');
        this.m_head.appendChild(script);
    }

    public loadFiles = () => 
    {
        // this.log(this.m_css_files);
        // this.log(this.m_js_files);

        for(var i:number = 0; i < this.m_css_files.length; ++i)
            this.loadStyle(this.m_css_files[i])

        this.loadScript(0);
    }

}


var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();
Run Code Online (Sandbox Code Playgroud)

如果要加载动态脚本列表,请将脚本写入属性,例如data-main,例如 <script src="scriptloader.js" data-main="file1.js,file2.js,file3.js,etc." ></script>
并执行aelement.getAttribute("data-main").split(',')

var target = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  // Note: this is for IE as IE doesn't support currentScript
  // this does not work if you have deferred loading with async
  // e.g. <script src="..." async="async" ></script>
  // https://web.archive.org/web/20180618155601/https://www.w3schools.com/TAgs/att_script_async.asp
  return scripts[scripts.length - 1];
})();

target.getAttribute("data-main").split(',')
Run Code Online (Sandbox Code Playgroud)

获得清单.


Tre*_*ent 8

jQuery.getScript()方法是Ajax的函数的速记(与数据类型属性:)$.ajax({ url: url,dataType: "script"})

如果您希望脚本可以缓存,请使用RequireJS或按照jQuery的示例扩展jQuery.getScript方法,类似于以下内容.

jQuery.cachedScript = function( url, options ) {

  // Allow user to set any option except for dataType, cache, and url
  options = $.extend( options || {}, {
    dataType: "script",
    cache: true,
    url: url
  });

  // Use $.ajax() since it is more flexible than $.getScript
  // Return the jqXHR object so we can chain callbacks
  return jQuery.ajax( options );
};

// Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
  console.log( textStatus );
});
Run Code Online (Sandbox Code Playgroud)

参考:jQuery.getScript()| jQuery API文档


Ble*_*der 5

jQuery 有$.getScript()

描述:使用 GET HTTP 请求从服务器加载 JavaScript 文件,然后执行它。


Haz*_*ass 5

您可以使用 JQuery 做到这一点:

$.getScript("ajax/test.js", function(data, textStatus, jqxhr) {
  console.log(data); //data returned
  console.log(textStatus); //success
  console.log(jqxhr.status); //200
  console.log('Load was performed.');
});
Run Code Online (Sandbox Code Playgroud)

这个链接应该有帮助:http : //api.jquery.com/jQuery.getScript/


aqm*_*aqm 5

我建议对AMD javascript类文件使用requirejs

在这里如何使用它的好例子

http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/


Luk*_*nga 5

为了编写我的插件,我需要在 JS 文件中加载外部脚本和样式,所有这些都是预定义的。为了实现这一点,我做了以下事情:

    this.loadRequiredFiles = function (callback) {
        var scripts = ['xx.js', 'yy.js'];
        var styles = ['zz.css'];
        var filesloaded = 0;
        var filestoload = scripts.length + styles.length;
        for (var i = 0; i < scripts.length; i++) {
            log('Loading script ' + scripts[i]);
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = scripts[i];
            script.onload = function () {
                log('Loaded script');
                log(this);
                filesloaded++;  // (This means increment, i.e. add one)
                finishLoad();
            };
            document.head.appendChild(script);
        }
        for (var i = 0; i < styles.length; i++) {
            log('Loading style ' + styles[i]);
            var style = document.createElement('link');
            style.rel = 'stylesheet';
            style.href = styles[i];
            style.type = 'text/css';
            style.onload = function () {
                log('Loaded style');
                log(this);
                filesloaded++;
                finishLoad();
            };
            document.head.appendChild(style);
        }
        function finishLoad() {
            if (filesloaded === filestoload) {
                callback();
            }
        }
    };
Run Code Online (Sandbox Code Playgroud)

上下文中的更多脚本:

function myPlugin() {

    var opts = {
        verbose: false
    };                          ///< The options required to run this function
    var self = this;            ///< An alias to 'this' in case we're in jQuery                         ///< Constants required for this function to work

    this.getOptions = function() {
        return opts;
    };

    this.setOptions = function(options) {
        for (var x in options) {
            opts[x] = options[x];
        }
    };

    /**
     * @brief Load the required files for this plugin
     * @param {Function} callback A callback function to run when all files have been loaded
     */
    this.loadRequiredFiles = function (callback) {
        var scripts = ['xx.js', 'yy.js'];
        var styles = ['zz.css'];
        var filesloaded = 0;
        var filestoload = scripts.length + styles.length;
        for (var i = 0; i < scripts.length; i++) {
            log('Loading script ' + scripts[i]);
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = scripts[i];
            script.onload = function () {
                log('Loaded script');
                log(this);
                filesloaded++;
                finishLoad();
            };
            document.head.appendChild(script);
        }
        for (var i = 0; i < styles.length; i++) {
            log('Loading style ' + styles[i]);
            var style = document.createElement('link');
            style.rel = 'stylesheet';
            style.href = styles[i];
            style.type = 'text/css';
            style.onload = function () {
                log('Loaded style');
                log(this);
                filesloaded++;
                finishLoad();
            };
            document.head.appendChild(style);
        }
        function finishLoad() {
            if (filesloaded === filestoload) {
                callback();
            }
        }
    };

    /**
     * @brief Enable user-controlled logging within this function
     * @param {String} msg The message to log
     * @param {Boolean} force True to log message even if user has set logging to false
     */
    function log(msg, force) {
        if (opts.verbose || force) {
            console.log(msg);
        }
    }

    /**
     * @brief Initialise this function
     */
    this.init = function() {
        self.loadRequiredFiles(self.afterLoadRequiredFiles);
    };

    this.afterLoadRequiredFiles = function () {
        // Do stuff
    };

}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

454660 次

最近记录:

7 年 前