Fügen Sie dynamisch ein Skript-Tag mit src hinzu, das document.write enthalten kann

160

Ich möchte ein Skript-Tag dynamisch in eine Webseite einfügen, habe jedoch keine Kontrolle über dessen src, sodass src = "source.js" möglicherweise so aussieht.

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

Jetzt normalerweise setzen

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

im Kopf funktioniert gut, aber gibt es eine andere Möglichkeit, source.js dynamisch mit so etwas wie innerHTML hinzuzufügen?

jsfiddle von dem, was ich versucht habe

Cadell Christo
quelle
2
Nach stundenlangem Kampf ist das Nachschreiben die Lösung! https://github.com/krux/postscribe/
Cadell Christo
Mögliches Duplikat des asynchronen Ladens von Javascript mit document.write
Michał Perłakowski

Antworten:

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
quelle
94

Sie können die document.createElement()Funktion folgendermaßen verwenden:

function addScript( src ) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  document.body.appendChild( s );
}
Sirko
quelle
Wie würden Sie diesen Async machen?
UKDataGeek
3
@mobile bloke: s.async = true;
Axlotl
s.setAttribute ('src', src); könnte sein s.src = src (ich denke?) Ich weiß, das ist nicht pcg
Brandito
67

Es gibt die onloadFunktion, die aufgerufen werden kann, wenn das Skript erfolgreich geladen wurde:

function addScript( src,callback) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  s.onload=callback;
  document.body.appendChild( s );
}
MSS
quelle
Etwas Neues gelernt. Nett!
mix3d
16

Ein nettes kleines Skript, das ich geschrieben habe, um mehrere Skripte zu laden:

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

Verwendung:

scriptLoader(['a.js','b.js'], function() {
    // use code from a.js or b.js
});
EliSherer
quelle
2
Sorry ... habe gerade eine bessere gefunden, die Abhängigkeiten zulässt stackoverflow.com/a/1867135/678780
EliSherer
5

Sie können versuchen, das folgende Code-Snippet zu verwenden.

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
quelle
4

Das ist Arbeit für mich.

Du kannst es überprüfen.

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
quelle
3

Wenn Skripte asynchron geladen werden, können sie document.write nicht aufrufen. Die Anrufe werden einfach ignoriert und eine Warnung wird an die Konsole geschrieben.

Sie können den folgenden Code verwenden, um das Skript dynamisch zu laden:

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

Dieser Ansatz funktioniert nur dann gut, wenn Ihre Quelle zu einer separaten Datei gehört.

Wenn Sie jedoch Quellcode als Inline-Funktionen haben, die Sie dynamisch laden und dem Skript-Tag andere Attribute hinzufügen möchten, z. B. Klasse, Typ usw., hilft Ihnen das folgende Snippet:

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

Nun, es gibt mehrere Möglichkeiten, wie Sie dynamisches Javascript einbinden können. Ich verwende dieses für viele Projekte.

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

Sie können create eine universelle Funktion aufrufen, mit der Sie so viele Javascript-Dateien wie nötig laden können. Hier finden Sie ein vollständiges Tutorial dazu.

Dynamisches Javascript richtig einfügen

Shubham Maurya
quelle
2
Zu Ihrer Information, Link funktioniert nicht, ich konnte den Artikel nicht woanders finden.
user1063287
1

Die einzige Möglichkeit, dies zu tun, besteht darin, sie document.writedurch eine eigene Funktion zu ersetzen, mit der Elemente am Ende Ihrer Seite angehängt werden. Mit jQuery ist das ziemlich einfach:

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

Wenn HTML in document.write in Blöcken wie im Fragenbeispiel angezeigt wird, müssen Sie die htmlToWriteSegmente puffern . Vielleicht so etwas:

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

Ich habe es versucht, indem ich jedes Skript rekursiv angehängt habe

Hinweis Wenn Ihre Skripte nacheinander abhängig sind, muss die Position synchron sein.

Die Hauptabhängigkeit sollte im Array als letztes vorhanden sein, damit die ersten Skripte sie verwenden können

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
quelle
1

Lädt voneinander abhängige Skripte mit der richtigen Reihenfolge.

Basierend auf der Antwort von Satyam Pathak , aber die Onload wurde behoben. Es wurde ausgelöst, bevor das Skript tatsächlich geladen wurde.

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
quelle
0

Hier ist ein minimiertes Snippet, der den gleichen Code wie Google Analytics und Facebook Pixel verwendet:

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

Ersetzen Sie https://example.com/foo.jsdurch Ihren Skriptpfad.

Moshe Simantov
quelle
0

Ein Einzeiler (kein wesentlicher Unterschied zu den obigen Antworten):

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