Выполнение внутри извлекается через 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 81

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

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

Это "просто работает" для меня с помощью 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