Как динамически вставить тег <script> через jQuery после загрузки страницы?


102

У меня проблемы с этим. Сначала я попытался установить теги сценария как строки, а затем с помощью jquery replaceWith () добавить их в документ после загрузки страницы:

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

Но у меня есть ошибки строкового литерала в этой переменной. Затем я попытался кодировать строку, например:

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

но отправив это для replaceWith()вывода только этой строки в браузер.

Может кто-нибудь, дайте мне знать, как вы будете динамически добавлять <script>тег в браузер после загрузки страницы, в идеале через jQuery?


Можете ли вы объяснить, чего вы пытаетесь достичь, добавляя <script>тег к документу?
— Pointy

Ответ @ Rocket - лучший, но если вы определенно хотите добавить встроенный скрипт из строки, вы просто передадите его eval()функции. Но использование eval()почти всегда предполагает, что есть лучший способ сделать то, что вы пытаетесь сделать.
— Ник,

мы пытаемся отложить загрузку сторонних объявлений до конца страницы. эти объявления вызываются через 2 тега сценария, поэтому я хотел запустить функцию после загрузки страницы, которая будет динамически их вставлять.
— Дуг,

2
Не все сторонние скрипты предназначены для отложенного выполнения. Если скрипт использует document.writeи вы вызываете его после загрузки страницы, он уничтожит страницу.
— bob с

1
Почему бы не импортировать эти теги в <iframe>элементы? Вы можете отложить установку <iframe>URL-адреса, пока не будете готовы.
— Pointy

Ответы:


103

Вы можете поместить сценарий в отдельный файл, а затем использовать $.getScriptдля его загрузки и запуска.

Пример:

$.getScript("test.js", function(){
    alert("Running test.js");
});

2
спасибо, но это вставит это в DOM? Я понимаю, что упустил эту важную информацию, что мне нужно, чтобы тег скрипта был вставлен в DOM, оценен, после чего он возвращает сторонний рекламный код для отображения на нашем сайте в определенном <div>.
— Дуг,

1
$.getScriptпросто загрузит файл .js через AJAX и выполнит его. Скрипт не обязательно должен находиться в DOM, чтобы иметь доступ к div на вашей странице.
— Rocket Hazmat

6
Но со $.getScript()сценарием нужно будет находиться в одном домене или удаленный домен и браузер должны будут поддерживать CORS.
— hippietrail

14
@hippietrail На самом деле это неправда. Он просто вставляет простой тег скрипта, который не требует CORS или того же домена. Я использую это, чтобы сократить код для загрузки, например, Google Analytics, и он отлично загружается. Фактически выполняемый код jquery очень похож на фрагмент кода GA.
— Крис Москини

39
Поскольку ответ от @hippietrail привлечет наибольшее внимание своими четырьмя положительными голосами, следует четко указать, что он неверен. Как подчеркивается в $.ajaxпримечаниях документации jQuery : «На запросы сценариев и JSONP не распространяются одни и те же ограничения политики происхождения». источник . Другими словами, вы $.getScriptможете извлекать файлы .js из других доменов, а не только из вашего собственного .
— EleventyOne

64

Попробуйте следующее:

<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


4
+1 для использования, appendчтобы добавить скрипт. Добавление вызывает немедленную оценку даже встроенного скрипта (именно то, что мне нужно). Спасибо
— Gone Coding

1
У меня в IE8 / 9 возникает множество проблем с этим подходом. А именно ошибки переполнения стека. Я прибег к методу $ .getScript () ниже, чтобы эта работа работала по всем направлениям.
— zmonteca 02

1
Да @jcoffland, это было написано в октябре 2010 года :)
— Bassem

Если страница, содержащая этот код, загружается с использованием AJAX, браузер выдаст предупреждение «Синхронный XMLHttpRequest в основном потоке устарел из-за его отрицательного воздействия на взаимодействие с конечным пользователем».
— Rajshekar Reddy 03

@Reddy Отличный комментарий. Это было опубликовано в октябре 2010 года, я уверен, что к настоящему времени этот метод больше не является допустимым / рекомендуемым подходом, пользователи должны действовать по своему усмотрению.
— Bassem

34

Вот правильный способ сделать это с помощью современного (2014) JQuery:

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

или если вы действительно хотите заменить div, вы можете сделать:

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

3
Или вместо .text ('здесь какой-то скрипт') можно написать .attr ('src', 'path_to_your_js_file')
— Сергей Максимчук

12

Более простой способ:

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

Вы также можете использовать эту форму для загрузки css.


6
Возможно, вы захотите не помещать строку </script>в свой источник, поскольку это может вызвать проблемы с синтаксическим
— анализом

2
спасение от последнего /$('head').append('<script src="your.js"><\/script>');
— помогло

5

Этот ответ технически аналогичен тому, что ответил jcoffland, или равен ему. Я просто добавил запрос, чтобы определить, присутствует ли сценарий уже или нет. Мне это нужно, потому что я работаю на веб-сайте интрасети с парой модулей, некоторые из которых совместно используют сценарии или приносят свои собственные, но эти сценарии не нужно загружать каждый раз снова. Я использую этот фрагмент уже более года в производственной среде, он отлично работает. Комментируя про себя: Да, я знаю, правильнее было бы спросить, существует ли функция ... :-)

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}

кстати. Я делаю то же самое с таблицами стилей: if (! $ ('Head> link [href = "widgets / css / widgets.css"]'). Length) {$ ('head'). Append ($ ('<link / > '). attr (' rel ',' stylesheet '). attr (' href ',' widgets / css / widgets.css '));}
— ddlab

2

Есть одно обходное решение, которое больше похоже на взлом, и я согласен, что это не самый элегантный способ сделать это, но работает на 100%:

Скажите, что ваш ответ AJAX похож на

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

Обратите внимание, что я специально пропустил закрывающий тег. Затем в скрипте, загружающем вышеуказанное, сделайте следующее:

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

Только не спрашивайте меня, почему :-) Это одна из тех вещей, к которым я пришел в результате отчаянных почти случайных испытаний и неудач.

У меня нет полных предложений о том, как это работает, но, что интересно, это НЕ будет работать, если вы добавите закрывающий тег в одну строку.

В такие моменты я чувствую, что успешно разделил на ноль.


3
Это не сработает, если закрывающий тег скрипта является цельным, поскольку браузер видит его как закрывающий тег для вашего скрипта, а не строковый литерал.
— Gone Coding

1
<\/script>будет действительным, хотя
— SP

Я думаю, что @ TrueBlueAussie высказался в ответ на ваш комментарий: «Только не спрашивайте меня, почему ... но, что интересно, это НЕ сработает, если вы добавите закрывающий тег в одну строку». Он объяснил почему, чтобы любой читатель, который хотел бы получить ответ лучше, чем «я не знаю», мог легче его найти. См. Также: javascript.crockford.com/script.html
— jacobq

1
@Sathvik правильный, согласно этой ссылке. Комментарий Эша, похоже, был ответом на комментарий, который был удален.
— Арлен Бейлер,

2

Пример:

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

Он должен работать. Я попробовал; тот же результат. Но когда я использовал это:

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

Это сработало для меня.

Изменить: я забыл #someelement(кстати, я мог бы использовать #someElementиз-за соглашений)

Самым важным здесь является + =, поэтому html добавляется, а не заменяется.

Оставьте комментарий, если не сработало. Я хочу вам помочь!


2

Вот более понятный способ - без jQuery - который добавляет скрипт в качестве последнего дочернего элемента <body>:

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

Но если вы хотите добавлять и загружать скрипты, используйте метод Rocket Hazmat .


-4

Если вы пытаетесь запустить динамически сгенерированный JavaScript, вам будет немного лучше, используя eval. Однако JavaScript - настолько динамичный язык, что в нем действительно не должно быть необходимости.

Если скрипт статический, то getScript-предложение Rocket - правильный выбор.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.