Aggiungi dinamicamente tag di script con src che può includere document.write


161

Voglio includere dinamicamente un tag di script in una pagina Web, tuttavia non ho alcun controllo su src, quindi src = "source.js" potrebbe apparire così.

document.write('<script type="text/javascript">')
document.write('alert("hello world")')
document.write('</script>')
document.write('<p>goodbye world</p>')

Ora ordinariamente mettendo

<script type="text/javascript" src="source.js"></script> 

nella testa funziona bene ma c'è un altro modo in cui posso aggiungere source.js in modo dinamico usando qualcosa come innerHTML?

jsfiddle di quello che ho provato


2
dopo ore di fatiche post-iscrizioni è la soluzione! https://github.com/krux/postscribe/
Cadell Christo,

Risposte:


210
var my_awesome_script = document.createElement('script');

my_awesome_script.setAttribute('src','http://example.com/site.js');

document.head.appendChild(my_awesome_script);

94

Puoi usare la document.createElement()funzione in questo modo:

function addScript( src ) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  document.body.appendChild( s );
}

Come renderebbe questo asincrono?
UKDataGeek,

3
@mobile bloke: s.async = true;
axlotl,

s.setAttribute ('src', src); potrebbe essere s.src = src (penso?) So che questo non è pcg
Brandito,

68

C'è la onloadfunzione che potrebbe essere chiamata quando lo script è stato caricato correttamente:

function addScript( src,callback) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  s.onload=callback;
  document.body.appendChild( s );
}

1
Ho imparato qualcosa di nuovo. Bello!
mix3d,

16

un bel piccolo script che ho scritto per caricare più script:

function scriptLoader(scripts, callback) {

    var count = scripts.length;

    function urlCallback(url) {
        return function () {
            console.log(url + ' was loaded (' + --count + ' more scripts remaining).');
            if (count < 1) {
                callback();
            }
        };
    }

    function loadScript(url) {
        var s = document.createElement('script');
        s.setAttribute('src', url);
        s.onload = urlCallback(url);
        document.head.appendChild(s);
    }

    for (var script of scripts) {
        loadScript(script);
    }
};

utilizzo:

scriptLoader(['a.js','b.js'], function() {
    // use code from a.js or b.js
});

2
Siamo spiacenti ... appena trovato uno migliore che permettono dipendenze stackoverflow.com/a/1867135/678780
EliSherer

5

Puoi provare a seguire il frammento di codice.

function addScript(attribute, text, callback) {
    var s = document.createElement('script');
    for (var attr in attribute) {
        s.setAttribute(attr, attribute[attr] ? attribute[attr] : null)
    }
    s.innerHTML = text;
    s.onload = callback;
    document.body.appendChild(s);
}

addScript({
    src: 'https://www.google.com',
    type: 'text/javascript',
    async: null
}, '<div>innerHTML</div>', function(){});

4

Questo è lavoro per me.

Puoi controllarlo.

var script_tag = document.createElement('script');
script_tag.setAttribute('src','https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js');
document.head.appendChild(script_tag);
window.onload = function() {
    if (window.jQuery) {  
        // jQuery is loaded  
        alert("ADD SCRIPT TAG ON HEAD!");
    } else {
        // jQuery is not loaded
        alert("DOESN'T ADD SCRIPT TAG ON HEAD");
    }
}


3

Quando gli script vengono caricati in modo asincrono, non possono chiamare document.write. Le chiamate verranno semplicemente ignorate e un avviso verrà scritto sulla console.

È possibile utilizzare il seguente codice per caricare lo script in modo dinamico:

var scriptElm = document.createElement('script');
scriptElm.src = 'source.js';
document.body.appendChild(scriptElm);

Questo approccio funziona bene solo quando l'origine appartiene a un file separato.

Ma se si dispone di codice sorgente come funzioni incorporate che si desidera caricare in modo dinamico e si desidera aggiungere altri attributi al tag script, ad esempio classe, tipo, ecc., Il seguente frammento sarebbe di aiuto:

var scriptElm = document.createElement('script');
scriptElm.setAttribute('class', 'class-name');
var inlineCode = document.createTextNode('alert("hello world")');
scriptElm.appendChild(inlineCode); 
target.appendChild(scriptElm);

2

Bene, ci sono molti modi in cui puoi includere javascript dinamico, io lo uso per molti dei progetti.

var script = document.createElement("script")
script.type = "text/javascript";
//Chrome,Firefox, Opera, Safari 3+
script.onload = function(){
console.log("Script is loaded");
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

Puoi chiamare creare una funzione universale che può aiutarti a caricare tutti i file javascript necessari. C'è un tutorial completo su questo qui.

Inserimento di Javascript dinamico nel modo giusto


2
a proposito, il link non funziona, non sono riuscito a trovare l'articolo altrove.
user1063287

1

l'unico modo per farlo è sostituire document.writecon la tua funzione che aggiungerà elementi in fondo alla tua pagina. È abbastanza semplice con jQuery:

document.write = function(htmlToWrite) {
  $(htmlToWrite).appendTo('body');
}

Se hai HTML in arrivo su document.write in blocchi come nell'esempio della domanda dovrai bufferizzare i htmlToWritesegmenti. Forse qualcosa del genere:

document.write = (function() {
  var buffer = "";
  var timer;
  return function(htmlPieceToWrite) {
    buffer += htmlPieceToWrite;
    clearTimeout(timer);
    timer = setTimeout(function() {
      $(buffer).appendTo('body');
      buffer = "";
    }, 0)
  }
})()

1

L'ho provato aggiungendo ricorsivamente ogni script

Nota Se gli script dipendono uno dopo l'altro, la posizione dovrà essere sincronizzata.

La dipendenza maggiore dovrebbe trovarsi all'ultimo posto nella matrice in modo che gli script iniziali possano utilizzarla

const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0

  
 const recursivelyAddScript = (script, cb) => {
  const el = document.createElement('script')
  el.src = script
  if(count < scripts.length) {
    count ++
    el.onload = recursivelyAddScript(scripts[count])
    document.body.appendChild(el)
  } else {
    console.log('All script loaded')
    return
  }
}
 
  recursivelyAddScript(scripts[count])


1

Carica script che dipendono l'uno dall'altro con il giusto ordine.

Basato sulla risposta di Satyam Pathak , ma risolto l'onload. È stato attivato prima che lo script fosse effettivamente caricato.

const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0

  
 const recursivelyAddScript = (script, cb) => {
  const el = document.createElement('script')
  el.src = script
  if(count < scripts.length) {
    count ++
    el.onload = () => recursivelyAddScript(scripts[count])
    document.body.appendChild(el)
  } else {
    console.log('All script loaded')
    return
  }
}
 
  recursivelyAddScript(scripts[count])


0

Ecco uno snippet minimizzato, lo stesso codice utilizzato da Google Analytics e Facebook Pixel:

!function(e,s,t){(t=e.createElement(s)).async=!0,t.src="https://example.com/foo.js",(e=e.getElementsByTagName(s)[0]).parentNode.insertBefore(t,e)}(document,"script");

Sostituisci https://example.com/foo.jscon il tuo percorso di script.


0

Un one-liner (nessuna differenza essenziale rispetto alle risposte sopra però):

document.body.appendChild(document.createElement('script')).src = 'source.js';
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.