Выполнение внутри извлекается через AJAX
есть div под названием "контент":
<div id="content"></div>
Он должен быть заполнен данными из php файла, с помощью AJAX, в том числе <script>
тег. Однако сценарий внутри этого тега не выполняется.
<div id="content"><!-- After AJAX loads the stuff that goes here -->
<script type="text/javascript">
//code
</script>
<!-- More stuff that DOES work here -->
</div>
10 ответов:
JavaScript, вставленный как текст DOM, не будет выполняться. Тем не менее, вы можете использовать динамический шаблон скрипт для достижения вашей цели. Основная идея состоит в том, чтобы переместить сценарий, который вы хотите выполнить, во внешний файл и создать тег сценария, когда вы получите свой ответ Ajax. Затем вы устанавливаете
src
атрибут вашего тега скрипта и вуаля, он загружает и выполняет внешний скрипт.Это другое сообщение StackOverflow также может быть полезно для вас:скрипты могут быть вставляется с innerHTML?.
я использовал этот код, он работает нормально
var arr = MyDiv.getElementsByTagName('script') for (var n = 0; n < arr.length; n++) eval(arr[n].innerHTML)//run script inside div
Если вы загружаете блок скрипта в div через Ajax следующим образом:
<div id="content"> <script type="text/javascript"> function myFunction() { //do something } myFunction(); </script> </div>
... он просто обновляет DOM вашей страницы, myFunction () не обязательно вызывается.
вы можете использовать метод обратного вызова Ajax, например, в jQuery ajax () метод, чтобы определить, что выполнять, когда запрос заканчивается.
то, что вы делаете, отличается от загрузки страницы с включенным в нее JavaScript из get-go (который получает казненный.)
пример того, как использовать обратный вызов успеха и обратный вызов ошибки после извлечения некоторого содержимого:
$.ajax({ type: 'GET', url: 'response.php', timeout: 2000, success: function(data) { $("#content").html(data); myFunction(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("error retrieving content"); }
еще один быстрый и грязный способ-это использовать eval () чтобы выполнить любой код сценария, который вы вставили в качестве текста DOM, если вы не хотите использовать jQuery или другую библиотеку.
вот скрипт, который будет оценивать все теги скрипта в тексте.
function evalJSFromHtml(html) { var newElement = document.createElement('div'); newElement.innerHTML = html; var scripts = newElement.getElementsByTagName("script"); for (var i = 0; i < scripts.length; ++i) { var script = scripts[i]; eval(script.innerHTML); } }
просто вызовите эту функцию после получения HTML с сервера. Будьте осторожны: с помощью
eval
может быть опасным.
Это "просто работает" для меня с помощью jQuery, если вы не пытаетесь добавить подмножество XHR-возвращенного HTML в документ. (См.этот отчет об ошибке показывает проблему с jQuery.)
вот пример, показывающий, что это работает:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>test_1.4</title> <script type="text/javascript" charset="utf-8" src="jquery.1.4.2.js"></script> <script type="text/javascript" charset="utf-8"> var snippet = "<div><span id='a'>JS did not run<\/span><script type='text/javascript'>" + "$('#a').html('Hooray! JS ran!');" + "<\/script><\/div>"; $(function(){ $('#replaceable').replaceWith($(snippet)); }); </script> </head> <body> <div id="replaceable">I'm going away.</div> </body> </html>
вот эквивалент выше: http://jsfiddle.net/2CTLH/
Если вы вводите что-то, что нуждается в теге сценария, вы можете получить неперехваченная синтаксическая ошибка и сказать незаконный токен. Чтобы избежать этого, не забудьте избежать прямых косых черт в тегах сценария закрытия. т. е.
var output += '<\/script>';
то же самое касается любых закрывающих тегов, таких как тег формы.
вот функция, которую вы можете использовать для анализа ответов AJAX, особенно если вы используете minifiedjs и хотите, чтобы он выполнял возвращенный Javascript или просто хотел анализировать сценарии без добавления их в DOM, он также обрабатывает ошибки исключения. Я использовал этот код в библиотеке php4sack, и он полезен вне библиотеки.
function parseScript(_source) { var source = _source; var scripts = new Array(); // Strip out tags while(source.toLowerCase().indexOf("<script") > -1 || source.toLowerCase().indexOf("</script") > -1) { var s = source.toLowerCase().indexOf("<script"); var s_e = source.indexOf(">", s); var e = source.toLowerCase().indexOf("</script", s); var e_e = source.indexOf(">", e); // Add to scripts array scripts.push(source.substring(s_e+1, e)); // Strip from source source = source.substring(0, s) + source.substring(e_e+1); } // Loop through every script collected and eval it for(var i=0; i<scripts.length; i++) { try { if (scripts[i] != '') { try { //IE execScript(scripts[i]); } catch(ex) //Firefox { window.eval(scripts[i]); } } } catch(e) { // do what you want here when a script fails // window.alert('Script failed to run - '+scripts[i]); if (e instanceof SyntaxError) console.log (e.message+' - '+scripts[i]); } } // Return the cleaned source return source; }
У меня был похожий пост здесь,addEventListener load on ajax load без jquery
Как я решил это было вставить вызовы функций в моей функции stateChange. Страница, которую я настроил, была 3 кнопками, которые загружали 3 разные страницы в contentArea. Поскольку мне нужно было знать, какая кнопка была нажата для загрузки страницы 1, 2 или 3, я мог легко использовать операторы if/else, чтобы определить, какая страница загружается, а затем какую функцию запускать. Что я пытался для этого нужно было зарегистрировать различные прослушиватели кнопок, которые будут работать только при загрузке конкретной страницы из-за идентификаторов элементов..
Так...
Если (страница 1 загружается, pageload = 1) запустите функцию registerListeners1
то же самое для страницы 2 или 3.
это сработало для меня, вызвав eval для каждого содержимого скрипта из ajax .сделано :
$.ajax({}).done(function (data) { $('div#content script').each(function (index, element) { eval(element.innerHTML); })
примечание: Я не писал параметры в $.ajax, который вы должны настроить согласно вашему Аяксу.
еще одна вещь, которую нужно сделать, это загрузить страницу со скриптом, таким как:
<div id="content" onmouseover='myFunction();$(this).prop( 'onmouseover', null );'> <script type="text/javascript"> function myFunction() { //do something } myFunction(); </script> </div>
это загрузит страницу, затем запустите скрипт и удалите обработчик событий, когда функция была запущена. Это не будет выполняться сразу после загрузки ajax, но если вы ждете, когда пользователь войдет в элемент div, это будет работать просто отлично.
PS. Требуется Jquery