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é


2
après des heures de difficultés, le post-abonnement est la solution! https://github.com/krux/postscribe/
Cadell Christo

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

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

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

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

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

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


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

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


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

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


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


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.


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';
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.