Запуск кода JavaScript, вызываемого AJAX - PullRequest
2 голосов
/ 11 февраля 2012

Мой сайт использует pushState для загрузки страниц.У меня есть одна проблема, я хочу использовать javascript на одной из страниц, но не могу, потому что он загружает все с AJAX.Так что мне делать?Мне сказали кое-что о "parseScript", но я не могу найти достаточно информации о нем.

- Пример -

Я загружаю с помощью AJAX На моей странице у меня есть этот скрипт:

<script type="text/javascript">
        function go(){
            alert('1');
        }
    </script>
<a href="javascript:void();" onClick="go();">GO!!!</a>

Ничего не происходит.

- Редактировать -

Если я открою отладчик Google Chrome: «Uncaught ReferenceError: go не определено» И тег не найден

Ответы [ 3 ]

2 голосов
/ 11 февраля 2012

Браузеры не обрабатывают <script> содержимое элемента, добавленное в документ с помощью targetElement.innerHTML. Это, вероятно, то, что вы сталкиваетесь.

Лучшее решение - использовать хорошо проверенную среду, такую ​​как jQuery, для решения подобных проблем. Они уже выяснили, как безопасно и правильно вводить скрипты в DOM. Нет смысла заново изобретать колесо, если вы абсолютно не можете сэкономить пропускную способность для библиотеки.


Один из способов исправить это - отделить JavaScript от HTML-кода в ответе Ajax, выполнив два запроса (возможно, медленнее) или структурировав JavaScript и HTML в объекте JSON (возможно, сложнее поддерживать).

Вот пример:

<script>

function load_content(){
  var req = new XMLHttpRequest();
  req.open("GET", "ajax.json", true);
  req.onreadystatechange = function (e){
    if (req.readyState === 4){
      if (req.status === 200){

        // these three lines inject your JavaScript and
        // HTML content into the DOM
        var json = JSON.parse(req.responseText);
        document.getElementById("target").innerHTML = json.html;
        eval(json.js);
      } else {
        console.log("Error", req.statusText);
      }
    }
  };
  req.send(null);
}

</script>

<a href="#" onclick="load_content()">Load more stuff</a>
<div id="target"></div>

Документ ajax.json на сервере выглядит так:

{
  "js": "window.bar = function (){ console.log(\"bar\"); return false; }",
  "html": "<p><a href=\"#\" onclick=\"bar();\">Log a message</a></p>"
}

Если вы выберете этот маршрут, вы должны либо:

  • Пространство имен ваших функций: MyApp.foo = function (){ ... }; или
  • явно добавляет ваши функции в глобальное пространство имен: window.foo = function (){ ... };.

Это потому, что eval выполняется в текущей области, поэтому ваши определения функций наследуют эту область и не будут доступны глобально. В моем примере я выбрал последний вариант, поскольку это просто тривиальный пример, но вы должны знать, почему это необходимо.

Пожалуйста, прочитайте Когда JavaScript eval () не является злом? , если вы решите реализовать это самостоятельно.

0 голосов
/ 11 февраля 2012

Если бы я сделал это, я бы использовал загрузочный вызов jquery. Для этого необходимо выполнить вызов ajax и проанализировать теги для элементов script / no-script.

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

0 голосов
/ 11 февраля 2012

Думаю, было бы полезно немного подробнее рассказать о том, как выполняется вызов Ajax и загружается контент.Тем не менее, несколько примечаний:

  • синтаксис для javascript: void () является недействительным.Это должен быть javascript: void (0).В связи с этим, использование javascript: void () в href тега привязки обычно является плохой практикой.Некоторые браузеры не поддерживают его.Если вы должны использовать тег, установите href на # и добавьте «return false;»на событие клика.
  • в этом случае в любом случае вы должны использовать тег кнопки вместо тега.
  • с учетом того, что вы предоставили, он должен работать (кроме ошибки синтаксиса с void ())
...