#jquery #ajax #dom
#jquery #ajax #dom
Вопрос:
Хорошо, я чувствую себя немного глупо, задавая этот вопрос. Есть любое количество обращений по похожим вопросам, но, похоже, я не могу понять это правильно. Если я изменяю DOM с помощью jQuery / Ajax, когда загруженный скрипт фактически анализируется / выполняется?
Приведенный ниже код работает на F / F, но не на Chrome или Opera. ‘Working’ означает, что он выполняет ‘do_init()’ без ошибок. Загруженный скрипт (фактически svg-файл; ‘file.svg’) определяет количество переменных, которые требуются для ‘do_init()’ (который находится в ‘статическом’ скрипте). Эти переменные видны в F / F, но не в Chrome или Opera («переменная xxx не определена»). Файл / скрипт правильно загружен в DOM во всех 3 случаях и содержит <svg>
, внутри которого находится <script>
.
Я могу заставить это работать (отображается svg) в Opera (или прервать в F / F), переупорядочив код, но не в Chrome. Использование .success и .complete не имеет значения.
Спасибо.
<head>
...
<script type="text/javascript" src="do_init.js"></script>
<script type="text/javascript"><![CDATA[
jQuery(document).ready(function() {
...
$("#submit").click(function(e){
e.preventDefault();
var jqxhr =
$("#svg").html(ajax_load).load("file.svg", function(response, status, xhr) {
if(status == "error") {
var msg = "Error: ";
$("#error").html(msg xhr.status " " xhr.statusText);
} else {
do_init(); // Ok in F/F, not in Chrome/Opera
}
});
});
});
]]></script>
</head>
<body>
<button id="submit" type="button">Click Me!</button>
<div id="svg"></div>
</body>
РЕДАКТИРОВАТЬ 1
Оказывается, что они никогда не выполняются — по крайней мере, в IE9, FF8, Chrome, Opera и Safari. Они выполняются в FF7. Я только что написал минимальную тестовую страницу, которая выполняет Ajax-загрузку скрипта, который является просто предупреждением. Это показывает предупреждение только в FF7. Я также пробовал скрипт, завернутый в <svg>
, который не имеет никакого значения.
Комментарии:
1. Возможно, вы захотите попробовать использовать $.get() вместо load(). Хотя в документации jQuery утверждается, что скрипты выполняются, если вы не укажете load () целевой объект, у меня возникли проблемы с загрузкой скриптов с помощью load (), которых у меня не было с использованием $.get()
2. Я только что попробовал get вместо этого, но у меня возникли проблемы с загрузкой DOM с помощью ответа — это легко с load. Я опубликую ответ, если смогу загрузить DOM и посмотреть, имеет ли это значение…
Ответ №1:
Это одна из причин, по которой рекомендуется размещать javascript в конце документа, в конце основного текста.
Как правило, javascript выполняется по мере его появления; если вы поместите его в начало документа, он будет выполняться в начале процесса загрузки, в конце — если он расположен в конце. Однако при использовании функций библиотеки «onLoad» или «DOMReady» вы откладываете выполнение на более позднее время.
Смотрите документы jQuery для получения дополнительной информации: http://api.jquery.com/ready /
Хотя JavaScript предоставляет событие load для выполнения кода при рендеринге страницы, это событие не запускается до тех пор, пока все ресурсы, такие как изображения, не будут полностью получены. В большинстве случаев скрипт можно запустить, как только иерархия DOM будет полностью построена. Обработчик, переданный в .ready(), гарантированно будет выполнен после того, как DOM будет готов, поэтому обычно это лучшее место для подключения всех других обработчиков событий и запуска другого кода jQuery. При использовании скриптов, которые полагаются на значение свойств стиля CSS, важно ссылаться на внешние таблицы стилей или внедрять элементы стиля, прежде чем ссылаться на скрипты.
РЕДАКТИРОВАТЬ Я неправильно истолковал детали вашего вопроса. Динамически загруженный скрипт анализируется немедленно, но onLoad
событие может (или не может!) запускаться в соответствии с аспектом HTTP-транспорта загруженного скрипта, а не при интерпретации загруженного скрипта. Обычно это нормально (хотя некоторые браузеры ненадежно запускают событие, то есть смотрят на вас), но время, которое вам нужно, — это не момент, когда скрипт был извлечен, а когда он фактически проанализирован и активен. Это должно происходить в пределах миллисекунд, что обычно делает разницу бессмысленной.
Существуют различные подходы к решению проблем с помощью этого метода, некоторые из которых обсуждаются здесь и здесь — однако, похоже, ни в одном конкретно не упоминается Chrome как источник проблем. Тем не менее, предлагаемый подход опроса для включенного скрипта (через тайм-аут) кажется наименее подверженным сбоям из предложений, хотя это также решение, которое мне нравится меньше всего.
Комментарии:
1. Хотя я не совсем уверен, что это актуально. Насколько я могу понять, события ready и load актуальны только при первоначальной загрузке документа. После запуска события все — я не думаю, что они представляют какую-либо ценность для последующих динамически загружаемых скриптов. Или они?
2. Спасибо, Крис, — просто просматриваю это сейчас. Между тем, я сделал интересное наблюдение, добавленное в качестве редактирования # 1 выше.
3. Я думаю, вы правы — getScript — это правильный путь. Мне пришлось все перестроить, чтобы убедиться, что вызов Ajax получает только скрипт, а не материал DOM, и я поместил вызов do_init в конец загруженного скрипта, и что все работает последовательно. Спасибо.