Ajoutez dynamiquement une balise de script avec src qui peut inclure document.write

161

Je veux inclure dynamiquement une balise de script dans une page Web, mais je n'ai aucun contrôle sur son src, donc src = "source.js" peut ressembler à ceci.

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

Maintenant ordinairement mettre

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

dans la tête fonctionne bien, mais y a-t-il un autre moyen d'ajouter dynamiquement source.js en utilisant quelque chose comme innerHTML?

jsfiddle de ce que j'ai essayé

Cadell Christo
la source
2
après des heures de difficultés, le post-abonnement est la solution! https://github.com/krux/postscribe/
Cadell Christo
Possible duplication du chargement asynchrone javascript avec document.write
Michał Perłakowski

Réponses:

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

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

document.head.appendChild(my_awesome_script);
dmp
la source
94

Vous pouvez utiliser la document.createElement()fonction comme ceci:

function addScript( src ) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  document.body.appendChild( s );
}
Sirko
la source
Comment feriez-vous cela asynchrone?
UKDataGeek
3
@mobile type: s.async = true;
axlotl
s.setAttribute ('src', src); pourrait être s.src = src (je pense?) Je sais que ce n'est pas pcg
Brandito
68

Il y a la onloadfonction, qui pourrait être appelée lorsque le script s'est chargé avec succès:

function addScript( src,callback) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  s.onload=callback;
  document.body.appendChild( s );
}
MSS
la source
1
J'ai appris quelque chose de nouveau. Agréable!
mix3d
16

un joli petit script que j'ai écrit pour charger plusieurs scripts:

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

usage:

scriptLoader(['a.js','b.js'], function() {
    // use code from a.js or b.js
});
EliSherer
la source
2
Désolé ... je viens de trouver un meilleur qui autorise les dépendances stackoverflow.com/a/1867135/678780
EliSherer
5

Vous pouvez essayer de suivre l'extrait de code.

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(){});
Vaenow
la source
4

C'est du travail pour moi.

Tu peux le vérifier.

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

jd savaj
la source
3

Lorsque les scripts sont chargés de manière asynchrone, ils ne peuvent pas appeler document.write. Les appels seront simplement ignorés et un avertissement sera écrit sur la console.

Vous pouvez utiliser le code suivant pour charger le script dynamiquement:

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

Cette approche ne fonctionne bien que lorsque votre source appartient à un fichier séparé.

Mais si vous avez du code source en tant que fonctions en ligne que vous souhaitez charger dynamiquement et que vous souhaitez ajouter d'autres attributs à la balise de script, par exemple la classe, le type, etc., alors l'extrait de code suivant vous aidera:

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

Eh bien, il existe plusieurs façons d'inclure du javascript dynamique, j'utilise celui-ci pour de nombreux projets.

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

Vous pouvez appeler create une fonction universelle qui peut vous aider à charger autant de fichiers javascript que nécessaire. Il y a un tutoriel complet à ce sujet ici.

Insérer du Javascript dynamique de la bonne manière

Shubham Maurya
la source
2
Pour info, le lien ne fonctionne pas, je n'ai pas trouvé l'article ailleurs.
user1063287
1

la seule façon de faire est de remplacer document.writepar votre propre fonction qui ajoutera des éléments au bas de votre page. C'est assez simple avec jQuery:

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

Si vous avez du HTML à venir dans document.write en morceaux comme l'exemple de question, vous aurez besoin de tamponner les htmlToWritesegments. Peut-être quelque chose comme ça:

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

Je l'ai essayé en ajoutant récursivement chaque script

Remarque Si vos scripts sont dépendants les uns après les autres, la position devra être synchronisée.

La dépendance majeure doit être en dernier dans le tableau afin que les scripts initiaux puissent l'utiliser

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

Satyam Pathak
la source
1

Charge les scripts qui dépendent les uns des autres dans le bon ordre.

Basé sur la réponse de Satyam Pathak , mais correction du chargement. Il a été déclenché avant le chargement du script.

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

kolorafa
la source
0

Voici un extrait minifié, même code que Google Analytics et Facebook Pixel utilise:

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

Remplacez https://example.com/foo.jspar votre chemin de script.

Moshe Simantov
la source
0

Un one-liner (pas de différence essentielle avec les réponses ci-dessus cependant):

document.body.appendChild(document.createElement('script')).src = 'source.js';
JohnW
la source