Wie füge ich nach dem Laden der Seite dynamisch ein <script> -Tag über jQuery ein?

101

Ich habe Probleme damit. Ich habe zuerst versucht, meine Skript-Tags als Zeichenfolgen festzulegen und sie dann nach dem Laden der Seite mit jquery replaceWith () zum Dokument hinzuzufügen:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

Aber ich habe String-Literal-Fehler auf dieser Var. Ich habe dann versucht, die Zeichenfolge wie folgt zu codieren:

var a = '&left;script type="text/javascript"&gt;some script here&lt;\/script&gt;';

Wenn Sie dies jedoch an die replaceWith()Ausgabe senden, wird nur diese Zeichenfolge an den Browser ausgegeben.

Kann mir bitte jemand mitteilen, wie Sie <script>nach dem Laden der Seite dynamisch ein Tag in den Browser einfügen würden, idealerweise über jQuery?

Doug
quelle
Können Sie erklären, was Sie erreichen möchten, indem Sie <script>dem Dokument ein Tag hinzufügen ?
Pointy
Die Antwort von @ Rocket ist die beste, aber wenn Sie definitiv ein Inline-Skript aus einer Zeichenfolge hinzufügen möchten, übergeben Sie es einfach an die eval()Funktion. Die Verwendung von eval()fast immer deutet jedoch darauf hin, dass es einen besseren Weg gibt, das zu tun, was Sie versuchen.
Nick
Wir versuchen, das Laden von Anzeigen von Drittanbietern auf das Ende der Seite zu verschieben. Diese Anzeigen werden über 2 Skript-Tags aufgerufen, daher wollte ich nach dem Laden der Seite eine Funktion ausführen, die sie dynamisch einwirft.
Doug
2
Nicht alle Skripte von Drittanbietern sind aufschiebbar. Wenn das Skript verwendet document.writeund Sie es nach dem Laden der Seite aufrufen, wird die Seite zerstört.
Bobince
1
Warum nicht diese Tags in <iframe>Elemente importieren ? Sie können das Festlegen der <iframe>URL verschieben, bis Sie bereit sind.
Pointy

Antworten:

103

Sie können das Skript in eine separate Datei $.getScripteinfügen und dann zum Laden und Ausführen verwenden.

Beispiel:

$.getScript("test.js", function(){
    alert("Running test.js");
});
Rakete Hazmat
quelle
2
Danke, aber wird das im DOM bleiben? Mir ist klar, dass ich diese wichtigen Informationen ausgelassen habe, dass das Skript-Tag in das DOM eingefügt und ausgewertet werden muss. Zu diesem Zeitpunkt wird der Anzeigencode eines Drittanbieters zurückgegeben, der auf unserer Website in einem bestimmten <div> angezeigt wird.
Doug
1
$.getScriptlädt einfach eine .js-Datei über AJAX und führt sie aus. Das Skript muss sich nicht im DOM befinden, um auf ein Div auf Ihrer Seite zugreifen zu können.
Rocket Hazmat
6
Aber mit $.getScript()dem Skript muss auf dem gleichen Gebiet sein , oder sowohl die Remote - Domäne und den Browser wird auf Unterstützung benötigen CORS.
Hippietrail
14
@ Hippietrail Das stimmt eigentlich nicht. Es wird nur ein einfaches altes Skript-Tag eingefügt, für das weder CORS noch dieselbe Domain erforderlich sind. Ich verwende dies, um beispielsweise den Code zum Laden von Google Analytics zu verkürzen, und er wird einwandfrei geladen. Hinter den Kulissen ist der tatsächlich ausgeführte JQuery-Code dem GA-Snippet ziemlich ähnlich.
Chris Moschini
39
Da die Antwort von @hippietrail mit ihren 4 positiven Stimmen die meiste Aufmerksamkeit auf sich ziehen wird, sollte nachdrücklich klargestellt werden, dass er falsch ist. Wie die jQuery-Dokumente in ihren $.ajaxNotizen hervorheben : "Skript- und JSONP-Anforderungen unterliegen nicht denselben Einschränkungen für Ursprungsrichtlinien." Quelle . Mit anderen Worten, Sie $.getScriptkönnen .js-Dateien aus anderen Domänen abrufen, nicht nur aus Ihren eigenen .
EleventyOne
64

Versuche Folgendes:

<script type="text/javascript">
// Use any event to append the code
$(document).ready(function() 
{
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "http://scriptlocation/das.js";
    // Use any selector
    $("head").append(s);
});

http://api.jquery.com/append

Bassem
quelle
4
+1 appendzum Hinzufügen eines Skripts. Das Anhängen bewirkt, dass sogar Inline-Skripte sofort ausgewertet werden (genau das, was ich brauchte). Danke
Gone Coding
1
Ich habe am Ende viele Probleme in IE8 / 9 mit diesem Ansatz. Nämlich Stapelüberlauffehler. Ich habe auf die unten stehende Methode $ .getScript () zurückgegriffen, um diese Arbeit auf ganzer Linie zu ermöglichen.
Zmonteca
1
Ja @jcoffland dies wurde im Oktober 2010 geschrieben :)
Bassem
Wenn die Seite mit diesem Code mit AJAX geladen wird, gibt der Browser die Warnung "Synchronous XMLHttpRequest on the main thread is veraltet, da sich dies nachteilig auf die Benutzererfahrung auswirkt" aus.
Rajshekar Reddy
@ Reddy Toller Kommentar. Dies wurde im Oktober 2010 veröffentlicht. Ich bin mir sicher, dass diese Methode mittlerweile kein gültiger / empfohlener Ansatz mehr ist. Benutzer müssen nach eigenem Ermessen vorgehen.
Bassem
33

Hier ist der richtige Weg, dies mit modernem (2014) JQuery zu tun:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .appendTo('head');
})

oder wenn Sie wirklich ein div ersetzen möchten, können Sie Folgendes tun:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .replaceAll('#someelement');
});
jcoffland
quelle
3
Oder stattdessen .text ('irgendein Skript hier') können Sie .attr ('src', 'path_to_your_js_file')
schreiben
11

Ein einfacher Weg ist:

$('head').append('<script type="text/javascript" src="your.js"></script>');

Sie können dieses Formular auch zum Laden von CSS verwenden.

Iman
quelle
5
Möglicherweise möchten Sie jedoch vermeiden, die Zeichenfolge </script>in Ihre Quelle einzufügen,
iX3
2
Dem letzten zu entkommen /hat den Trick für mich getan:$('head').append('<script src="your.js"><\/script>');
Jerik
5

Diese Antwort ist technisch ähnlich oder entspricht der Antwort von jcoffland. Ich habe gerade eine Abfrage hinzugefügt, um festzustellen, ob bereits ein Skript vorhanden ist oder nicht. Ich brauche das, weil ich auf einer Intranet-Website mit einigen Modulen arbeite, von denen einige Skripte freigeben oder ihre eigenen mitbringen, aber diese Skripte müssen nicht jedes Mal neu geladen werden. Ich verwende dieses Snippet seit mehr als einem Jahr in einer Produktionsumgebung. Es funktioniert wie ein Charme. Kommentar zu mir selbst: Ja, ich weiß, es wäre richtiger zu fragen, ob eine Funktion existiert ... :-)

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}
ddlab
quelle
Übrigens. Ich mache dasselbe mit Stylesheets: if (! $ ('Head> link [href = "widgets / css / widgets.css"]'). Length) {$ ('head'). Append ($ ('<link / > '). attr (' rel ',' stylesheet '). attr (' href ',' widgets / css / widgets.css '));}
ddlab
2

Es gibt eine Problemumgehung, die eher nach einem Hack klingt, und ich stimme zu, dass dies nicht die eleganteste Art ist, aber zu 100% funktioniert:

Angenommen, Ihre AJAX-Antwort ist so etwas wie

<b>some html</b>
<script>alert("and some javscript")

Beachten Sie, dass ich das schließende Tag absichtlich übersprungen habe. Gehen Sie dann in dem Skript, das das oben genannte lädt, wie folgt vor:

$.ajax({
    url: "path/to/return/the-above-js+html.php",
    success: function(newhtml){
        newhtml += "<";
        newhtml += "/script>";
        $("head").append(newhtml);
    }
});

Frag mich einfach nicht warum :-) Dies ist eines der Dinge, zu denen ich als Ergebnis verzweifelter, fast zufälliger Versuche gekommen bin und die fehlgeschlagen sind.

Ich habe keine vollständigen Vorschläge, wie es funktioniert, aber interessanterweise funktioniert es NICHT, wenn Sie das schließende Tag in einer Zeile anhängen.

In Zeiten wie diesen habe ich das Gefühl, erfolgreich durch Null geteilt zu haben.

Asche
quelle
3
Es funktioniert nicht, wenn das schließende Skript-Tag einteilig ist, da der Browser es als schließendes Tag für Ihr Skript anstelle eines Zeichenfolgenliteral betrachtet.
Gone Coding
1
<\/script>wäre aber gültig
SP
Ich denke, @ TrueBlueAussies Punkt war eine Antwort auf Ihren Kommentar "Fragen Sie mich einfach nicht warum ... aber interessanterweise funktioniert es NICHT, wenn Sie das schließende Tag in einer Zeile anhängen." Er erklärte, warum, damit Leser, die eine bessere Antwort als "Ich weiß nicht" wünschen, diese leichter finden könnten. Siehe auch: javascript.crockford.com/script.html
iX3
1
@Sathvik ist laut diesem Link korrekt. Ashs Kommentar scheint eine Antwort auf eine gewesen zu sein, die entfernt wurde.
Arlen Beiler
2

Beispiel:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

Es sollte funktionieren. Ich versuchte es; gleiches Ergebnis. Aber als ich das benutzte:

var length = 1;
var html = "";
for (var i = 0; i < length; i++) {
    html += '<div id="codeSnippet"></div>';
    html += '<script type="text/javascript">';
    html += 'your script here';
    html += '</script>';
}
$('#someElement').replaceWith(a);

Das hat bei mir funktioniert.

Edit: Ich habe das vergessen #someelement(übrigens möchte ich vielleicht verwenden#someElement wegen Konventionen verwenden)

Das Wichtigste hier ist das + =, damit das HTML hinzugefügt und nicht ersetzt wird.

Hinterlasse einen Kommentar, wenn es nicht funktioniert hat. Ich würde dir gerne helfen!

Santinobonora
quelle
2

Hier ist ein viel klarerer Weg - keine Notwendigkeit für jQuery -, der ein Skript als letztes untergeordnetes Element von Folgendes hinzufügt <body>:

document.body.innerHTML +='<script src="mycdn.js"><\/script>'

Wenn Sie jedoch Skripte hinzufügen und laden möchten, verwenden Sie die Methode von Rocket Hazmat .

Gagik Sargsyan
quelle
-4

Wenn Sie versuchen, dynamisch generiertes JavaScript auszuführen, ist die Verwendung von JavaScript etwas besser eval. JavaScript ist jedoch eine so dynamische Sprache, dass Sie das wirklich nicht brauchen sollten.

Wenn das Skript statisch ist, ist Rockets getScript-Vorschlag der richtige Weg.

Magnar
quelle