Динамично загрузите файл JavaScript

Вы можете взглянуть на образец Facebook Auth , чтобы увидеть реализацию потока Auth, о котором говорит Том. Для Azure AD это почти то же самое. Я опубликовал некоторые детали реализации на , как получить Azure Active Directory B2C, работающий с Bot Framework?

Обновить

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

158
задан Cole Johnson 11 April 2014 в 22:01
поделиться

10 ответов

Можно записать динамические теги script (использующий Прототип ):

new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});

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

Мы часто хотим наш подчиненный код очень следующей строки и любим писать что-то как:

if (iNeedSomeMore) {
    Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
    myFancyMethod(); // cool, no need for callbacks!
}

существует умный способ ввести зависимости от сценария без потребности обратных вызовов. Просто необходимо вытянуть сценарий через синхронный запрос Ajax и оценка сценарий на глобальном уровне.

при использовании Прототипа метод Script.load похож на это:

var Script = {
    _loadedScripts: [],
    include: function(script) {
        // include script only once
        if (this._loadedScripts.include(script)) {
            return false;
        }
        // request file synchronous
        var code = new Ajax.Request(script, {
            asynchronous: false,
            method: "GET",
            evalJS: false,
            evalJSON: false
        }).transport.responseText;
        // eval code on global level
        if (Prototype.Browser.IE) {
            window.execScript(code);
        } else if (Prototype.Browser.WebKit) {
            $("head").first().insert(Object.extend(
                new Element("script", {
                    type: "text/javascript"
                }), {
                    text: code
                }
            ));
        } else {
            window.eval(code);
        }
        // remember included script
        this._loadedScripts.push(script);
    }
};
79
ответ дан Milap 23 November 2019 в 21:41
поделиться

все крупнейшие библиотеки JavaScript как jscript, прототип, YUI имеют поддержку загрузки файлов сценария. Например, в YUI, после загрузки ядра можно сделать следующее для загрузки календарного управления

var loader = new YAHOO.util.YUILoader({

    require: ['calendar'], // what components?

    base: '../../build/',//where do they live?

    //filter: "DEBUG",  //use debug versions (or apply some
                        //some other filter?

    //loadOptional: true, //load all optional dependencies?

    //onSuccess is the function that YUI Loader
    //should call when all components are successfully loaded.
    onSuccess: function() {
        //Once the YUI Calendar Control and dependencies are on
        //the page, we'll verify that our target container is 
        //available in the DOM and then instantiate a default
        //calendar into it:
        YAHOO.util.Event.onAvailable("calendar_container", function() {
            var myCal = new YAHOO.widget.Calendar("mycal_id", "calendar_container");
            myCal.render();
        })
     },

    // should a failure occur, the onFailure function will be executed
    onFailure: function(o) {
        alert("error: " + YAHOO.lang.dump(o));
    }

 });

// Calculate the dependency and insert the required scripts and css resources
// into the document
loader.insert();
0
ответ дан Darren Kopp 23 November 2019 в 21:41
поделиться

я использовал еще одно решение, которое я нашел в сети..., этот находится под creativecommons и этим проверки, если источник был включен до вызова функции ...

можно найти файл здесь: include.js

/** include - including .js files from JS - bfults@gmail.com - 2005-02-09
 ** Code licensed under Creative Commons Attribution-ShareAlike License 
 ** http://creativecommons.org/licenses/by-sa/2.0/
 **/              
var hIncludes = null;
function include(sURI)
{   
  if (document.getElementsByTagName)
  {   
    if (!hIncludes)
    {
      hIncludes = {}; 
      var cScripts = document.getElementsByTagName("script");
      for (var i=0,len=cScripts.length; i < len; i++)
        if (cScripts[i].src) hIncludes[cScripts[i].src] = true;
    }
    if (!hIncludes[sURI])
    {
      var oNew = document.createElement("script");
      oNew.type = "text/javascript";
      oNew.src = sURI;
      hIncludes[sURI]=true;
      document.getElementsByTagName("head")[0].appendChild(oNew);
    }
  }   
} 
3
ответ дан Pierre Spring 23 November 2019 в 21:41
поделиться

у кого-либо есть лучший путь?

я думаю, просто добавив, что сценарий к телу был бы легче тогда добавление его к последнему узлу на странице. Как насчет этого:

function include(url) {
  var s = document.createElement("script");
  s.setAttribute("type", "text/javascript");
  s.setAttribute("src", url);
  document.body.appendChild(s);
}
3
ответ дан Joseph Pecoraro 23 November 2019 в 21:41
поделиться

Вот некоторый пример кода, который я нашел..., что у кого-либо есть лучший путь?

  function include(url)
  {
    var s = document.createElement("script");
    s.setAttribute("type", "text/javascript");
    s.setAttribute("src", url);
    var nodes = document.getElementsByTagName("*");
    var node = nodes[nodes.length -1].parentNode;
    node.appendChild(s);
  }
8
ответ дан Adam 23 November 2019 в 21:41
поделиться

Я сделал в основном то же самое, что Вы сделали Adam, но с небольшой модификацией для проверки я добавлял к главному тегу, чтобы сделать задание. Я просто создал включать функцию (код ниже) для обработки и сценария и css файлов.

Эта функция также проверяет, чтобы удостовериться, что файл сценария или CSS не был уже загружен динамично. Это не проверяет на кодированные значения руки и, возможно, был лучший способ сделать это, но это служило цели.

function include( url, type ){
    // First make sure it hasn't been loaded by something else.
    if( Array.contains( includedFile, url ) )
        return;

    // Determine the MIME-type
    var jsExpr = new RegExp( "js$", "i" );
    var cssExpr = new RegExp( "css$", "i" );
    if( type == null )
        if( jsExpr.test( url ) )
            type = 'text/javascript';
        else if( cssExpr.test( url ) )
            type = 'text/css';

    // Create the appropriate element.
    var tag = null;
    switch( type ){
        case 'text/javascript' :
            tag = document.createElement( 'script' );
            tag.type = type;
            tag.src = url;
            break;
        case 'text/css' :
            tag = document.createElement( 'link' );
            tag.rel = 'stylesheet';
            tag.type = type;
            tag.href = url;
            break;
    }

    // Insert it to the <head> and the array to ensure it is not
    // loaded again.
    document.getElementsByTagName("head")[0].appendChild( tag );
    Array.add( includedFile, url );
}
20
ответ дан Prisoner ZERO 23 November 2019 в 21:41
поделиться

Я использовал намного менее сложная версия недавно с jQuery:

<script src="scripts/jquery.js"></script>
<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  var $head = $("head");
  for (var i = 0; i < js.length; i++) {
    $head.append("<script src=\"" + js[i] + "\"></scr" + "ipt>");
  }
</script>

Это работало отлично в каждом браузере, в котором я протестировал его: IE6/7, Firefox, Safari, Opera.

Обновление: версия jQuery меньше:

<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  for (var i = 0, l = js.length; i < l; i++) {
    document.getElementsByTagName("head")[0].innerHTML += ("<script src=\"" + js[i] + "\"></scr" + "ipt>");
  }
</script>
27
ответ дан Clomp 23 November 2019 в 21:41
поделиться

Техника, которую мы используем на работе, должна запросить файл JavaScript с помощью запроса Ajax и затем оценки () возврат. Если Вы пользуетесь библиотекой прототипа, они поддерживают эту функциональность в своем Ajax. Вызов запроса.

2
ответ дан 17 of 26 23 November 2019 в 21:41
поделиться

Просто узнанный о замечательной особенности в YUI 3 (во время записи доступного в предварительном выпуске). Можно легко вставить зависимости в библиотеки YUI и во "внешние" модули (что Вы ищете) без слишком большого количества кода: Загрузчик YUI.

Это также отвечает на Ваш второй вопрос относительно функции, вызванной, как только внешний модуль загружается.

Пример:

YUI({
    modules: {
        'simple': {
            fullpath: "http://example.com/public/js/simple.js"
        },
        'complicated': {
            fullpath: "http://example.com/public/js/complicated.js"
            requires: ['simple']  // <-- dependency to 'simple' module
        }
    },
    timeout: 10000
}).use('complicated', function(Y, result) {
    // called as soon as 'complicated' is loaded
    if (!result.success) {
        // loading failed, or timeout
        handleError(result.msg);
    } else {
        // call a function that needs 'complicated'
        doSomethingComplicated(...);
    }
});

Работавший отлично для меня и имеет преимущество руководящих зависимостей. Обратитесь к документации YUI для примера с календарем YUI 2.

3
ответ дан Kariem 23 November 2019 в 21:41
поделиться

Я настроил часть вышеупомянутого сообщения с рабочим примером. Здесь мы можем дать CSS и js в том же массиве также.

$(document).ready(function(){

if (Array.prototype.contains === undefined) {
Array.prototype.contains = function (obj) {
    var i = this.length;
    while (i--) { if (this[i] === obj) return true; }
    return false;
};
};

/* define object that will wrap our logic */
var jsScriptCssLoader = {

jsExpr : new RegExp( "js$", "i" ),
cssExpr : new RegExp( "css$", "i" ),
loadedFiles: [],

loadFile: function (cssJsFileArray) {
    var self = this;
    // remove duplicates with in array
    cssJsFileArray.filter((item,index)=>cssJsFileArray.indexOf(item)==index)
    var loadedFileArray = this.loadedFiles;
    $.each(cssJsFileArray, function( index, url ) {
            // if multiple arrays are loaded the check the uniqueness
            if (loadedFileArray.contains(url)) return;
            if( self.jsExpr.test( url ) ){
                $.get(url, function(data) {
                    self.addScript(data);
                });

            }else if( self.cssExpr.test( url ) ){
                $.get(url, function(data) {
                    self.addCss(data);
                });
            }

            self.loadedFiles.push(url);
    });

    // don't load twice accross different arrays

},
addScript: function (code) {
    var oNew = document.createElement("script");
    oNew.type = "text/javascript";
    oNew.textContent = code;
    document.getElementsByTagName("head")[0].appendChild(oNew);
},
addCss: function (code) {
    var oNew = document.createElement("style");
    oNew.textContent = code;
    document.getElementsByTagName("head")[0].appendChild(oNew);
}

};


//jsScriptCssLoader.loadFile(["css/1.css","css/2.css","css/3.css"]);
jsScriptCssLoader.loadFile(["js/common/1.js","js/2.js","js/common/file/fileReader.js"]);
});
0
ответ дан 23 November 2019 в 21:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: