Выполнение <script> внутри <div>, извлеченного AJAX

Там есть div, называемый "Content":

<div id="content"></div>

Он должен быть заполнен данными из файла PHP, AJAX, включая тег <script>. Однако 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>

Ответ 1

JavaScript, вставленный как текст DOM, не будет выполняться. Однако вы можете использовать динамический шаблон сценария для достижения вашей цели. Основная идея - переместить скрипт, который вы хотите выполнить во внешний файл, и создать тег сценария, когда вы получите ответ Ajax. Затем вы устанавливаете атрибут src вашего тега скрипта и voila, он загружает и выполняет внешний script.

Этот другой пост StackOverflow также может быть вам полезен: Можно ли вставлять скрипты с помощью innerHTML?.

Ответ 2

Я использовал этот код, он отлично работает

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div

Ответ 3

Если вы загрузите блок script в свой 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() для выполнения любого script кода, который вы вставили в виде текста DOM, если вы не хотите использовать jQuery или другую библиотеку.

Ответ 4

Вот script, который будет оценивать все теги script в тексте.

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 может быть опасным.

Демо: http://plnkr.co/edit/LA7OPkRfAtgOhwcAnLrl?p=preview

Ответ 5

Это "работает" для меня, используя jQuery, если вы не пытаетесь добавить подкомпонент HTML-HTML, возвращенный XHR. (См. этот отчет об ошибке, показывающий проблему с 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/

Ответ 6

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

var output += '<\/script>';

То же самое касается любых закрывающих тегов, например тега формы.

Ответ 7

Вот функция, которую вы можете использовать для анализа ответов 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;
 }

Ответ 8

У меня был похожий пост, addEventListener load на загрузку ajax БЕЗ jQuery

Как я решил, нужно было вставлять вызовы в функции в моей функции stateChange. На странице, которую я установил, было 3 кнопки, которые загружали бы 3 разных страницы в contentArea. Поскольку я должен был знать, какая кнопка была нажата для загрузки страниц 1, 2 или 3, я мог бы легко использовать операторы if/else, чтобы определить, какая страница загружается, а затем какую функцию запускать. То, что я пытался сделать, это зарегистрировать разные прослушиватели кнопок, которые будут работать только тогда, когда конкретная страница была загружена из-за идентификаторов элементов.

так...

if (страница 1 загружается, pageload = 1)  run functionListeners1

то то же самое для страниц 2 или 3.

Ответ 9

Я тоже застрял в одной и той же проблеме, после того, как много ударов и испытаний я нашел решение.

$.ajax({
            type: 'GET',
            url: '/url',
            data: {
                q: str
            },
            success: function(data){
                $("#divname").html(data);
                //your js code here
           }
});

Это работает отлично.

Ответ 10

Это сработало для меня, вызвав eval на каждый script контент из ajax.done:

$.ajax({}).done(function (data) {      
    $('div#content script').each(function (index, element) { eval(element.innerHTML); 
})  

Примечание. Я не записывал параметры в $.ajax, которые вы должны настроить в соответствии с вашим аяксом.

Ответ 11

Еще одна задача - загрузить страницу с помощью script, например:

<div id="content" onmouseover='myFunction();$(this).prop( 'onmouseover', null );'>
<script type="text/javascript">
function myFunction() {
  //do something
}
myFunction();
</script>
</div>

Это загрузит страницу, затем запустит script и удалит обработчик событий, когда функция будет запущена. Это не будет запускаться сразу после загрузки ajax, но если вы ожидаете, что пользователь войдет в элемент div, это будет работать нормально.

PS. Требуется JQuery