Динамически загружать JS внутри JS

У меня есть динамическая веб-страница, где мне нужно импортировать внешний JS файл (в состоянии IF) в другой файл javascript.

Я попытался найти приемлемое решение, но оно не сработало.

Я попытался загрузить JS файл в DOM с помощью document.createElement(), но он также не работал. По-видимому, Js был загружен в DOM, но не был доступен в текущем JS файле.

Решение в jQuery также будет прекрасно

Ответ 1

jQuery $.getScript() иногда является ошибкой, поэтому я использую его собственную реализацию, например:

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

и используйте его как:

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

Ответ 2

Я предполагаю, что в вашем DOM-решении вы сделали что-то вроде:

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

Прежде всего, это не сработает, потому что script не добавляется в дерево документа, поэтому он не будет загружен. Кроме того, даже когда вы это делаете, выполнение javascript продолжается, пока загружается другой script, поэтому его содержимое будет недоступно вам до тех пор, пока script не будет полностью загружен.

Вы можете прослушивать событие script 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

Ответ 3

Мне нужно сделать это часто, поэтому я использую это:

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);

Для получения дополнительной информации см. этот сайт Как включить файл JavaScript в другой файл JavaScript?, который является источником моей идеи функции.

Ответ 4

Вы можете динамически загружать 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.');
});

Ответ 5

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();

Если вас интересует typescript -версия, используемая для создания этого:

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();

Ответ 6

Метод jQuery.getScript() является сокращением функции Ajax (с атрибутом dataType: $.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 );
});

Ссылка: jQuery.getScript() | Документация API jQuery

Ответ 7

Вы можете сделать это с помощью 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.');
});

эта ссылка должна помочь: http://api.jquery.com/jQuery.getScript/

Ответ 8

jQuery имеет $.getScript():

Описание. Загрузите файл JavaScript с сервера с помощью HTTP-запроса GET и выполните его.

Ответ 10

Чтобы авторизовать мой плагин, мне нужно было загрузить внешние скрипты и стили внутри 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();
            }
        }
    };

Больше script в контексте:

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
    };

}

Ответ 11

Вы можете использовать метод jQuery $.getScript(), но если вам нужна более полная функция, yepnope.js - ваш выбор. Он поддерживает условную загрузку скриптов и таблиц стилей и упрощает их использование.

Ответ 12

Вот немного lib для загрузки файлов javascript и CSS динамически:

https://github.com/todotresde/javascript-loader

Я думаю, полезно загружать файлы css и js в порядке и динамически.

Поддержка расширения для загрузки любой библиотеки, которую вы хотите, а не только основного файла, вы можете использовать ее для загрузки пользовательских файлов.

то есть:.

<html>
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="scripts/javascript-loader.js" type="text/javascript" charset="utf-8" ></script>    
    <script type="text/javascript">
        $(function() {

            registerLib("threejs", test);

            function test(){
                console.log(THREE);
            }

            registerLib("tinymce", draw);

            function draw(){
                tinymce.init({selector:'textarea'});
            }

        }); 
    </script>
</head>
<body>
    <textarea>Your content here.</textarea>
</body>

Ответ 13

Если у вас много файлов с зависимостями, используйте AMD/RequireJS. http://requirejs.org/