Dynamiczne ładowanie pliku JavaScript

Jak można niezawodnie i dynamicznie załadować plik JavaScript? To może być użyte do implementacji modułu lub komponentu, który po "zainicjowaniu" komponent dynamicznie załaduje wszystkie potrzebne Skrypty biblioteki JavaScript na żądanie.

Klient, który używa komponentu, nie jest zobowiązany do załadowania wszystkich plików skryptów biblioteki (i ręcznego wstawiania znaczników <script> do swojej strony internetowej), które implementują ten komponent - tylko 'główny' plik skryptu komponentu.

Jak mainstreamowe biblioteki JavaScript (Prototype, jQuery, etc)? czy te narzędzia łączą wiele plików JavaScript w jedną redystrybucyjną wersję pliku skryptu? A może robią jakieś dynamiczne ładowanie pomocniczych skryptów 'bibliotecznych'?

Dodatek do tego pytania: czy istnieje sposób na obsługę zdarzenia po załadowaniu dynamicznie dołączonego pliku JavaScript? Prototype ma document.observe dla zdarzeń w całym dokumencie. Przykład:

document.observe("dom:loaded", function() {
  // initially hide all containers for tab content
  $$('div.tabcontent').invoke('hide');
});

Jakie są dostępne zdarzenia dla elementu skryptu?

Author: Cole Johnson, 2008-08-21

28 answers

Możesz pisać dynamiczne znaczniki skryptów (używając Prototype):

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

Problem polega na tym, że nie wiemy Kiedy zewnętrzny plik skryptu jest w pełni załadowany.

Często chcemy nasz zależny kod na następnej linii i chcemy napisać coś w stylu:

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

Istnieje inteligentny sposób wprowadzania zależności od skryptu bez konieczności wywoływania zwrotnego. Po prostu musisz pobrać skrypt za pomocą synchronicznego żądania AJAX i ewalować skrypt na poziomie globalnym.

Jeśli użyjesz prototypu skryptu.metoda load wygląda tak:

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);
    }
};
 87
Author: aemkei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-07 11:33:16

Nie istnieje import / include / require w javascript, ale istnieją dwa główne sposoby osiągnięcia tego, co chcesz:

1 - możesz go załadować wywołaniem AJAX, a następnie użyć eval.

Jest to najprostszy sposób, ale jest ograniczony do Twojej domeny ze względu na ustawienia bezpieczeństwa Javascript, a korzystanie z eval otwiera drzwi do błędów i hacków.

2-Dodaj znacznik skryptu z adresem URL skryptu w HTML.

Zdecydowanie najlepszy sposób. Skrypt można załadować nawet z zagraniczny serwer, i jest czysty, gdy używasz parsera przeglądarki do oceny kodu. Możesz umieścić znacznik w nagłówku strony internetowej lub na dole treści.

Oba te rozwiązania są omówione i zilustrowane tutaj.

Jest pewien problem, o którym musisz wiedzieć. Oznacza to, że zdalnie załadujesz kod. Nowoczesne przeglądarki internetowe załadują plik i będą nadal wykonywać bieżący skrypt, ponieważ ładują wszystko asynchronicznie, aby poprawić występy.

Oznacza to, że jeśli użyjesz tych sztuczek bezpośrednio, nie będziesz mógł użyć nowo załadowanego kodu w następnej linii po tym, jak poprosiłeś o załadowanie, ponieważ będzie on nadal wczytywany.

Np: my_lovely_script.js zawiera MySuperObject

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

Następnie przeładowujesz stronę uderzając F5. I to działa! Mylące...

Co z tym zrobić ?

Cóż, możesz użyć hacka, który autor sugeruje w linku, który ci dałem. Podsumowując, dla ludzi w pośpiechu, używa zdarzenia en do uruchomienia funkcji callback, gdy skrypt jest ładowany. Możesz więc umieścić cały kod za pomocą zdalnej biblioteki w funkcji zwrotnej. Np.:

function loadScript(url, callback)
{
    // adding the script tag to the head as suggested before
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = url;

   // then bind the event to the callback function 
   // there are several events for cross browser compatibility
   script.onreadystatechange = callback;
   script.onload = callback;

   // fire the loading
   head.appendChild(script);
}

Następnie piszesz kod, którego chcesz użyć po załadowaniu skryptu w funkcji lambda:

var myPrettyCode = function() {
    // here, do what ever you want
};

Następnie uruchom to wszystko:

loadScript("my_lovely_script.js", myPrettyCode);
Ok, rozumiem. Ale pisanie tego wszystkiego jest męczące.

Cóż, w takim przypadku, można użyć jak zawsze fantastyczny darmowy framework jQuery, który pozwala zrobić bardzo to samo w jednej linijce:

$.getScript("my_lovely_script.js", function() {
    alert("Script loaded and executed.");
    // here you can use anything you defined in the loaded script
});
 76
Author: Milap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-07 11:35:17

Użyłem ostatnio znacznie mniej skomplikowanej wersji z 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>
Działa świetnie w każdej przeglądarce, w której testowałem: IE6 / 7, Firefox, Safari, Opera.

Update: wersja bez 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>
 29
Author: travis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-30 00:41:57

Zrobiłem zasadniczo to samo, co Ty Adam, ale z niewielką modyfikacją, aby upewnić się, że dodaję do znacznika głowy, aby wykonać zadanie. Po prostu stworzyłem funkcję include (kod poniżej) do obsługi zarówno plików skryptowych, jak i css.

Ta funkcja sprawdza również, czy skrypt lub plik CSS nie został załadowany dynamicznie. Nie sprawdza wartości kodowanych ręcznie i może był lepszy sposób, aby to zrobić, ale służył celowi.

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
Author: palehorse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-06 16:34:20

Another awesome answer

$.getScript("my_lovely_script.js", function(){


   alert("Script loaded and executed.");
  // here you can use anything you defined in the loaded script

 });

Https://stackoverflow.com/a/950146/671046

 14
Author: Naveed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:20

Oto przykładowy kod, który znalazłem... czy ktoś ma lepszy sposób?

  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);
  }
 9
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 22:00:13

Jeśli masz już załadowany jQuery, powinieneś użyć $.getScript .

Ma to przewagę nad innymi odpowiedziami tutaj, ponieważ masz wbudowaną funkcję zwrotną (aby zagwarantować, że skrypt zostanie załadowany przed uruchomieniem zależnego kodu) i możesz kontrolować buforowanie.

 6
Author: Muhd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-13 20:37:23

Jeśli chcesz załadować skrypt SYNC , musisz dodać tekst skryptu bezpośrednio do znacznika HTML HEAD. Dodanie go jako wywoła obciążenie asynchroniczne . Aby synchronicznie załadować tekst skryptu z zewnętrznego pliku, użyj XHR. Poniżej krótka próbka (używa części innych odpowiedzi w tym i innych postach):

/*sample requires an additional method for array prototype:*/

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 ScriptLoader = {
LoadedFiles: [],

LoadFile: function (url) {
    var self = this;
    if (this.LoadedFiles.contains(url)) return;

    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                self.LoadedFiles.push(url);
                self.AddScript(xhr.responseText);
            } else {
                if (console) console.error(xhr.statusText);
            }
        }
    };
    xhr.open("GET", url, false);/*last parameter defines if call is async or not*/
    xhr.send(null);
},

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

/*Load script file. ScriptLoader will check if you try to load a file that has already been loaded (this check might be better, but I'm lazy).*/

ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
/*this will be executed right after upper lines. It requires jquery to execute. It requires a HTML input with id "tb1"*/
$(function () { alert($('#tb1').val()); });
 4
Author: Sielu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-06 08:40:32
Czy ktoś ma lepszy sposób?

Myślę, że samo dodanie skryptu do ciała byłoby łatwiejsze, a następnie dodanie go do ostatniego węzła na stronie. Co ty na to:

function include(url) {
  var s = document.createElement("script");
  s.setAttribute("type", "text/javascript");
  s.setAttribute("src", url);
  document.body.appendChild(s);
}
 3
Author: Joseph Pecoraro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 22:10:08

Użyłem jeszcze jednego rozwiązania, które znalazłem w sieci ... ten jest pod creativecommons i sprawdza, czy źródło zostało włączone przed wywołaniem funkcji ...

Plik można znaleźć tutaj: include.js

/** include - including .js files from JS - [email protected] - 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
Author: Pierre Spring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 14:50:30

Właśnie dowiedziałem się o wielkiej funkcji w YUI 3 (w momencie pisania dostępne w wersji przedpremierowej). Możesz łatwo wstawiać zależności do bibliotek YUI i do "zewnętrznych" modułów (tego, czego szukasz) bez zbytniego kodu: Yui Loader .

Odpowiada również na drugie pytanie dotyczące wywoływanej funkcji zaraz po załadowaniu zewnętrznego modułu.

Przykład:

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

Pracował dla mnie doskonale i ma tę zaletę, że zarządza zależności. Zobacz dokumentację Yui dla przykładu z kalendarzem YUI 2 .

 3
Author: Kariem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-26 00:14:38

JEST NOWY proponowany standard ECMA o nazwie dynamic import , niedawno włączony do Chrome i Safari.

const moduleSpecifier = './dir/someModule.js';

import(moduleSpecifier)
   .then(someModule => someModule.foo()); // executes foo method in someModule
 3
Author: Alister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 09:57:57

Dynamiczny Moduł import wylądował w Firefoksie 67+.

(async () => {
   await import('./synth/BubbleSynth.js')
})()

Z obsługą błędów:

(async () => {
    await import('./synth/BubbleSynth.js').catch((error) => console.log('Loading failed' + error))
})()

Działa również dla wszelkiego rodzaju bibliotek niemodułowych, w tym przypadku Lib jest dostępny w obiekcie window, w stary sposób, ale tylko na żądanie, co jest miłe.

Przykład użycia suncalc.js , serwer musi mieć Korsarz to działa to A niech to!

(async () => {
 await import('https://cdnjs.cloudflare.com/ajax/libs/suncalc/1.8.0/suncalc.min.js')
 .then(function(){
   let times = SunCalc.getTimes(new Date(), 51.5,-0.1);
   console.log("Golden Hour today in London: " + times.goldenHour.getHours() + ':' + times.goldenHour.getMinutes() + ". Take your pics!")
  })
})()

Https://caniuse.com/#feat=es6-module-dynamic-import

 3
Author: NVRM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-09 17:19:49

Technika, której używamy w pracy, polega na żądaniu pliku javascript za pomocą żądania AJAX, a następnie zwracaniu EVAL (). Jeśli używasz biblioteki prototypów, obsługują tę funkcjonalność w Ajax.Proszę o telefon.

 2
Author: 17 of 26,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 23:03:53

Jquery rozwiązał to dla mnie za pomocą its .funkcja append () - używane do załadowania kompletnego pakietu jQuery ui

/*
 * FILENAME : project.library.js
 * USAGE    : loads any javascript library
 */
    var dirPath = "../js/";
    var library = ["functions.js","swfobject.js","jquery.jeditable.mini.js","jquery-ui-1.8.8.custom.min.js","ui/jquery.ui.core.min.js","ui/jquery.ui.widget.min.js","ui/jquery.ui.position.min.js","ui/jquery.ui.button.min.js","ui/jquery.ui.mouse.min.js","ui/jquery.ui.dialog.min.js","ui/jquery.effects.core.min.js","ui/jquery.effects.blind.min.js","ui/jquery.effects.fade.min.js","ui/jquery.effects.slide.min.js","ui/jquery.effects.transfer.min.js"];

    for(var script in library){
        $('head').append('<script type="text/javascript" src="' + dirPath + library[script] + '"></script>');
    }

Aby użyć - w nagłówku twojego html/php/etc po zaimportowaniu jquery.js wystarczy załączyć ten jeden plik jak tak, aby załadować w całości biblioteki dołączając go do głowy...

<script type="text/javascript" src="project.library.js"></script>
 2
Author: JM Design,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-14 21:07:03

Zachowaj to miłe, krótkie, proste i łatwe do utrzymania! :]

// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
    FULL_PATH + 'plugins/script.js'      // Script example
    FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library 
    FULL_PATH + 'plugins/crypto-js/hmac-sha1.js',      // CryptoJS
    FULL_PATH + 'plugins/crypto-js/enc-base64-min.js'  // CryptoJS
];

function load(url)
{
    var ajax = new XMLHttpRequest();
    ajax.open('GET', url, false);
    ajax.onreadystatechange = function ()
    {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4)
        {
            switch(ajax.status)
            {
                case 200:
                    eval.apply( window, [script] );
                    console.log("library loaded: ", url);
                    break;
                default:
                    console.log("ERROR: library not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

 // initialize a single load 
load('plugins/script.js');

// initialize a full load of scripts
if (s.length > 0)
{
    for (i = 0; i < s.length; i++)
    {
        load(s[i]);
    }
}

Ten kod jest po prostu krótkim funkcjonalnym przykładem, który Może wymagać dodatkowej funkcjonalności dla pełnego wsparcia na dowolnej (lub danej) platformie.

 2
Author: tfont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-08 01:16:30

Wiem, że moja odpowiedź jest trochę za późno na to pytanie, ale tutaj jest świetny artykuł w www.html5rocks.com - zanurz się głęboko w mrocznych wodach script loading .

W tym artykule stwierdzono, że jeśli chodzi o obsługę przeglądarki, najlepszym sposobem dynamicznego ładowania plików JavaScript bez blokowania renderowania zawartości jest następujący sposób:

Biorąc pod uwagę, że masz cztery Skrypty o nazwie script1.js, script2.js, script3.js, script4.js, możesz to zrobić za pomocą stosując async = false :

[
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
].forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.head.appendChild(script);
});

Teraz, Spec mówi : Pobierz razem, wykonaj w kolejności, jak tylko wszystkie pliki zostaną pobrane.

Firefox nie mam pojęcia, co to jest "asynchroniczne", ale tak się składa, że wykonuję Skrypty dodawane przez JS w kolejności, w jakiej są dodawane.

Safari 5.0 mówi: Rozumiem "asynchroniczne", ale nie rozumiem ustawiania go na "false" w JS. Wykonam Twoje skrypty, jak tylko wylądują, w dowolnej kolejności.

IE No pomysł na "async" , ale istnieje obejście za pomocą "onreadystatechange".

Wszystko inne mówi: Jestem twoim przyjacielem, zrobimy to zgodnie z zasadami.

Teraz Pełny kod z obejściem IE

var scripts = [
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
];
var src;
var script;
var pendingScripts = [];
var firstScript = document.scripts[0];

// Watch scripts load in IE
function stateChange() {
  // Execute as many scripts in order as we can
  var pendingScript;
  while (pendingScripts[0] && pendingScripts[0].readyState == 'loaded') {
    pendingScript = pendingScripts.shift();
    // avoid future loading events from this script (eg, if src changes)
    pendingScript.onreadystatechange = null;
    // can't just appendChild, old IE bug if element isn't closed
    firstScript.parentNode.insertBefore(pendingScript, firstScript);
  }
}

// loop through our script urls
while (src = scripts.shift()) {
  if ('async' in firstScript) { // modern browsers
    script = document.createElement('script');
    script.async = false;
    script.src = src;
    document.head.appendChild(script);
  }
  else if (firstScript.readyState) { // IE<10
    // create a script and add it to our todo pile
    script = document.createElement('script');
    pendingScripts.push(script);
    // listen for state changes
    script.onreadystatechange = stateChange;
    // must set src AFTER adding onreadystatechange listener
    // else we’ll miss the loaded event for cached scripts
    script.src = src;
  }
  else { // fall back to defer
    document.write('<script src="' + src + '" defer></'+'script>');
  }
}

Kilka trików i minifikacja później, to 362 bajty

!function(e,t,r){function n(){for(;d[0]&&"loaded"==d[0][f];)c=d.shift(),c[o]=!i.parentNode.insertBefore(c,i)}for(var s,a,c,d=[],i=e.scripts[0],o="onreadystatechange",f="readyState";s=r.shift();)a=e.createElement(t),"async"in i?(a.async=!1,e.head.appendChild(a)):i[f]?(d.push(a),a[o]=n):e.write("<"+t+' src="'+s+'" defer></'+t+">"),a.src=s}(document,"script",[
  "//other-domain.com/1.js",
  "2.js"
])
 2
Author: asmmahmud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-03 15:42:40

Istnieją Skrypty zaprojektowane specjalnie do tego celu.

Yepnope.js jest wbudowany w Modernizr i lab.js jest bardziej zoptymalizowaną (ale mniej przyjazną dla użytkownika wersją.

Nie polecałbym tego robić za pomocą dużej biblioteki, takiej jak jquery lub prototype-ponieważ jedną z głównych zalet programu do ładowania skryptów jest możliwość wczesnego ładowania skryptów - nie powinieneś czekać, aż jQuery i wszystkie elementy dom załadują się przed uruchomieniem sprawdzania, aby sprawdzić, czy chcesz dynamicznie załadować skrypt.

 1
Author: 1nfiniti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-13 22:01:51

Napisałem prosty moduł, który automatyzuje zadanie importowania / włączania skryptów modułów w JavaScript. Spróbuj i oszczędź trochę opinii! :) Szczegółowe wyjaśnienie kodu znajduje się w tym wpisie na blogu: http://stamat.wordpress.com/2013/04/12/javascript-require-import-include-modules/

var _rmod = _rmod || {}; //require module namespace
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark the root directory of your library, any library


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };

    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

//you can rename based on your liking. I chose require, but it can be called include or anything else that is easy for you to remember or write, except import because it is reserved for future use.
var require = function(script_name) {
    var np = script_name.split('.');
    if (np[np.length-1] === '*') {
        np.pop();
        np.push('_all');
    }

    script_name = np.join('.');
    var uri = _rmod.libpath + np.join('/')+'.js';
    if (!_rmod.loading.scripts.hasOwnProperty(script_name) 
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri, 
            _rmod.requireCallback, 
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

// ----- USAGE -----

require('ivar.util.array');
require('ivar.util.string');
require('ivar.net.*');

ready(function(){
    //do something when required scripts are loaded
});
 1
Author: stamat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-12 16:55:25

Jestem zagubiony we wszystkich tych próbkach, ale dzisiaj musiałem załadować zewnętrzny .js z mojej głównej .js i ja to zrobilem:

document.write("<script src='https://www.google.com/recaptcha/api.js'></script>");
 1
Author: adrianTNT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-04 10:08:06

Tutaj {[3] } jest prosty z callback i obsługą IE:

function loadScript(url, callback) {

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState) { //IE
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" || script.readyState == "complete") {
                script.onreadystatechange = null;
                callback();
            }
        };
    } else { //Others
        script.onload = function () {
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

loadScript("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {

     //jQuery loaded
     console.log('jquery loaded');

});
 1
Author: Jacob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 09:40:04

Coś w tym stylu...

<script>
     $(document).ready(function() {
          $('body').append('<script src="https://maps.googleapis.com/maps/api/js?key=KEY&libraries=places&callback=getCurrentPickupLocation" async defer><\/script>');
     });
</script>
 1
Author: James Arnold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 01:22:12

Oto prosty przykład funkcji do ładowania plików JS. Istotne punkty:

  • nie potrzebujesz jQuery, więc możesz użyć go początkowo, aby załadować również jQuery.plik js
  • jest asynchroniczny z wywołaniem zwrotnym
  • zapewnia ładowanie tylko raz, ponieważ przechowuje obudowę z zapisem załadowanych adresów URL, unikając w ten sposób korzystania z sieci
  • w przeciwieństwie do jQuery $.ajax lub $.getScript możesz używać nonces, rozwiązując tym samym problemy z CSP unsafe-inline. Wystarczy skorzystać z nieruchomości script.nonce
var getScriptOnce = function() {

    var scriptArray = []; //array of urls (closure)

    //function to defer loading of script
    return function (url, callback){
        //the array doesn't have such url
        if (scriptArray.indexOf(url) === -1){

            var script=document.createElement('script');
            script.src=url;
            var head=document.getElementsByTagName('head')[0],
                done=false;

            script.onload=script.onreadystatechange = function(){
                if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
                    done=true;
                    if (typeof callback === 'function') {
                        callback();
                    }
                    script.onload = script.onreadystatechange = null;
                    head.removeChild(script);

                    scriptArray.push(url);
                }
            };

            head.appendChild(script);
        }
    };
}();

Teraz używasz go po prostu przez

getScriptOnce("url_of_your_JS_file.js");
 1
Author: João Pimentel Ferreira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-26 20:54:24

Absurdalny jednowiersz, dla tych, którzy uważają, że wczytywanie biblioteki js nie powinno zająć więcej niż jednej linijki kodu: P

await new Promise((resolve, reject) => {let js = document.createElement("script"); js.src="mylibrary.js"; js.onload=resolve; js.onerror=reject; document.body.appendChild(js)});

Oczywiście jeśli skrypt, który chcesz zaimportować jest modułem, możesz użyć import(...) funkcja.

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 10:10:46

Dzięki obietnicom można to uprościć w ten sposób. Funkcja Loader:

  const loadCDN = src =>
    new Promise((resolve, reject) => {
      if (document.querySelector(`head > script[src="${src}"]`) !== null) return resolve()
      const script = document.createElement("script")
      script.src = src
      script.async = true
      document.head.appendChild(script)
      script.onload = resolve
      script.onerror = reject
    })

Usage (asynchroniczne / oczekujące):

await loadCDN("https://.../script.js")

Użycie (Obietnica):

loadCDN("https://.../script.js").then(res => {}).catch(err => {})

Uwaga: było jedno podobne rozwiązanie, ale nie sprawdza, czy skrypt jest już załadowany i ładuje skrypt za każdym razem. Ten sprawdza własność src.

 1
Author: radulle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-06 13:49:20

Dla tych z Was, którzy kochają jednoślady:

import('./myscript.js');

Są szanse, że dostaniesz błąd, jak:

Dostęp do skryptu pod adresem ' http://..../ myscriptjs " z pochodzenia " http://127.0.0.1 ' został zablokowany przez CORS policy: No Nagłówek 'Access-Control-Allow-Origin' jest obecny na żądanym zasoby.

W takim przypadku możesz wrócić do:

fetch('myscript.js').then(r => r.text()).then(t => new Function(t)());
 1
Author: Ludmil Tinkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-16 11:42:51

Wszystkie główne biblioteki javascript, takie jak jscript, prototype, YUI mają wsparcie dla ładowania plików skryptów. Na przykład, w YUI, po załadowaniu rdzenia możesz wykonać następujące czynności, aby załadować kontrolkę kalendarza

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
Author: Darren Kopp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-28 04:27:40

Poprawiłem niektóre z powyższych postów z działającym przykładem. Tutaj możemy dać css i js również w tej samej tablicy.

$(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
Author: VG P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-23 20:52:57