Jak dynamicznie wstawić tag <script> przez jQuery po załadowaniu strony?

102

Mam problemy z uruchomieniem tego. Najpierw próbowałem ustawić moje tagi skryptu jako ciągi, a następnie użyć jquery replaceWith (), aby dodać je do dokumentu po załadowaniu strony:

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

Ale dostałem literalne błędy w tej zmiennej. Następnie próbowałem zakodować ciąg w następujący sposób:

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

ale wysyłanie tego do replaceWith()wyprowadza tylko ten ciąg do przeglądarki.

Czy ktoś może mi powiedzieć, jak byś się zajął dynamicznym dodawaniem <script>tagu do przeglądarki po załadowaniu strony, najlepiej przez jQuery?

Doug
źródło
Czy możesz wyjaśnić, co próbujesz osiągnąć, dodając <script>tag do dokumentu?
Pointy
Odpowiedź @ Rocket jest najlepsza, ale jeśli na pewno chcesz dodać skrypt wbudowany z ciągu, po prostu przekaż go do eval()funkcji. Ale użycie eval()prawie zawsze sugeruje, że istnieje lepszy sposób na zrobienie tego, co próbujesz zrobić.
Nick
próbujemy odłożyć ładowanie reklam firm zewnętrznych do końca strony. te reklamy są wywoływane za pomocą 2 tagów skryptu, więc po załadowaniu strony chciałem uruchomić funkcję, która wrzuca je dynamicznie.
Doug
2
Nie wszystkie skrypty innych firm są przeznaczone do odroczenia. Jeśli skrypt używa document.writei wywołasz go po załadowaniu strony, zniszczy stronę.
bobince
1
Dlaczego nie zaimportować tych tagów w <iframe>elementach? Możesz odłożyć ustawianie <iframe>adresu URL, aż będziesz gotowy.
Pointy

Odpowiedzi:

103

Możesz umieścić skrypt w osobnym pliku, a następnie użyć go $.getScriptdo załadowania i uruchomienia.

Przykład:

$.getScript("test.js", function(){
    alert("Running test.js");
});
Rocket Hazmat
źródło
2
dzięki, ale czy to umieści go w DOM? Zdaję sobie sprawę, że pominąłem tę ważną informację, że potrzebuję, aby tag skryptu został wstawiony do DOM, oceniony, po czym zwraca kod reklamy innej firmy do wyświetlenia w naszej witrynie w określonym <div>.
Doug
1
$.getScriptpo prostu załaduje plik .js przez AJAX i uruchomi go. Skrypt nie musi znajdować się w DOM, aby mieć dostęp do elementu DIV na Twojej stronie.
Rocket Hazmat
6
Ale $.getScript()skrypt będzie musiał znajdować się w tej samej domenie lub zarówno zdalnej domenie, jak i przeglądarka będzie musiała obsługiwać CORS.
hippietrail
14
@hippietrail To właściwie nieprawda. Po prostu wstawia zwykły znacznik skryptu, który nie wymaga CORS ani tej samej domeny. Używam tego na przykład do skrócenia kodu do ładowania Google Analytics i ładuje się dobrze. Za kulisami rzeczywisty kod jquery, który działa, jest w rzeczywistości bardzo podobny do fragmentu GA.
Chris Moschini
39
Ponieważ odpowiedź od @hippietrail przyciągnie najwięcej uwagi dzięki 4 głosom za, należy wyraźnie zaznaczyć, że jest niepoprawny. Jak podkreślają dokumenty jQuery w swoich $.ajaxuwagach: „Żądania skryptów i JSONP nie podlegają tym samym ograniczeniom zasad pochodzenia”. źródło . Innymi słowy, $.getScriptmoże pobierać pliki .js z innych domen, nie tylko z własnej .
EleventyOne
64

Spróbuj wykonać następujące czynności:

<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
źródło
4
+1 do użycia w appendcelu dodania skryptu. Dołączanie powoduje, że nawet skrypt wbudowany jest natychmiast oceniany (właśnie tego potrzebowałem). Dzięki
Gone Coding
1
W wyniku tego podejścia mam wiele problemów w IE8 / 9. Mianowicie błędy przepełnienia stosu. Skorzystałem z metody $ .getScript () poniżej, aby mieć to we wszystkich przypadkach.
zmonteca
1
Tak @jcoffland, to zostało napisane w październiku 2010 r. :)
Bassem,
Jeśli strona zawierająca ten kod zostanie załadowana przy użyciu technologii AJAX, przeglądarka wyświetli ostrzeżenie „Synchroniczne żądanie XMLHttpRequest w wątku głównym jest przestarzałe, ponieważ ma szkodliwy wpływ na środowisko użytkownika końcowego”.
Rajshekar Reddy
@Reddy Wielki komentarz. Zostało to opublikowane w październiku 2010, jestem pewien, że do tej pory ta metoda nie jest już prawidłowym / zalecanym podejściem, użytkownicy muszą postępować według własnego uznania.
Bassem
34

Oto poprawny sposób na zrobienie tego z nowoczesnym (2014) JQuery:

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

lub jeśli naprawdę chcesz zamienić element div, możesz zrobić:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .replaceAll('#someelement');
});
jcoffland
źródło
3
Albo zamiast tego .text ('tu jakiś skrypt') możesz napisać .attr ('src', 'path_to_your_js_file')
Serhii Maksymchuk
12

Prostszy sposób to:

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

Możesz również użyć tego formularza do załadowania css.

iman
źródło
6
Możesz jednak unikać umieszczania łańcucha </script>w swoim źródle, ponieważ może to powodować problemy z analizą: stackoverflow.com/questions/236073/ ...
jacobq
2
ucieczka ostatnia /$('head').append('<script src="your.js"><\/script>');
załatwiła
5

Ta odpowiedź jest technicznie podobna lub równa temu, na co odpowiedział jcoffland. Właśnie dodałem zapytanie, aby wykryć, czy skrypt już istnieje, czy nie. Potrzebuję tego, ponieważ pracuję w witrynie intranetowej z kilkoma modułami, z których niektóre udostępniają skrypty lub przynoszą własne, ale te skrypty nie muszą być ładowane za każdym razem. Używam tego fragmentu od ponad roku w środowisku produkcyjnym, działa jak urok. Komentując sobie: Tak, wiem, bardziej poprawne byłoby pytanie, czy funkcja istnieje ... :-)

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}
ddlab
źródło
przy okazji. Robię to samo z arkuszami stylów: if (! $ ('Head> link [href = "widgets / css / widgets.css"]'). Length) {$ ('head'). Append ($ ('<link / > '). attr (' rel ',' stylesheet '). attr (' href ',' widgets / css / widgets.css '));}
ddlab
2

Jest jedno obejście, które brzmi bardziej jak włamanie i zgadzam się, że nie jest to najbardziej elegancki sposób, ale działa w 100%:

Powiedz, że Twoja odpowiedź AJAX jest podobna do

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

Zauważ, że celowo pominąłem tag zamykający. Następnie w skrypcie, który ładuje powyższe, wykonaj następujące czynności:

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

Tylko nie pytaj mnie dlaczego :-) To jedna z tych rzeczy, do których doszedłem w wyniku desperackich, prawie przypadkowych prób i niepowodzeń.

Nie mam pełnych sugestii, jak to działa, ale co ciekawe, NIE zadziała, jeśli dodasz tag zamykający w jednej linii.

W takich chwilach mam wrażenie, że udało mi się podzielić przez zero.

Boyan
źródło
3
Nie zadziała, jeśli zamykający tag skryptu jest w jednym kawałku, ponieważ przeglądarka widzi go jako tag zamykający dla twojego skryptu zamiast literału ciągu.
Gone Coding
1
<\/script>byłby jednak ważny
SP
Myślę, że uwaga @ TrueBlueAussie była odpowiedzią na twój komentarz "Po prostu nie pytaj mnie dlaczego ... ale co ciekawe, NIE zadziała, jeśli dodasz tag zamykający w jednej linii." Wyjaśnił dlaczego, aby czytelnicy, którzy chcieliby mieć lepszą odpowiedź niż „nie wiem”, mogli ją łatwiej znaleźć. Zobacz też: javascript.crockford.com/script.html
jacobq
1
@Sathvik ma rację, zgodnie z tym linkiem. Komentarz Asha wydaje się być odpowiedzią na ten, który został usunięty.
Arlen Beiler
2

Przykład:

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

Powinno działać. Próbowałem tego; ten sam wynik. Ale kiedy użyłem tego:

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

To zadziałało dla mnie.

Edycja: zapomniałem #someelement(przy okazji mogę chcieć użyć z #someElementpowodu konwencji)

Najważniejsze jest tutaj + =, więc kod HTML jest dodawany, a nie zastępowany.

Zostaw komentarz, jeśli to nie zadziałało. Chciałbym ci pomóc!

santinobonora
źródło
2

Oto znacznie jaśniejszy sposób - nie ma potrzeby korzystania z jQuery - który dodaje skrypt jako ostatnie dziecko <body>:

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

Ale jeśli chcesz dodawać i ładować skrypty, użyj metody Rocket Hazmat .

Gagik Sargsyan
źródło
-4

Jeśli próbujesz uruchomić dynamicznie generowany JavaScript, byłoby nieco lepiej, gdybyś użył eval. Jednak JavaScript jest tak dynamicznym językiem, że naprawdę nie powinieneś tego potrzebować.

Jeśli skrypt jest statyczny, najlepszym getScriptrozwiązaniem jest sugestia Rocketa.

Magnar
źródło