Браузеры не обрабатывают <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 () не является злом? , если вы решите реализовать это самостоятельно.