Загружает ли содержимое AJAX содержимое "document.ready"?
Вчера у меня возникла проблема, когда обработчик событий .on('click')
, который я назначал, работал неправильно. Оказывается, потому что я пытался применить этот .on('click')
до того, как этот элемент существовал в DOM, потому что он загружался через AJAX и, следовательно, еще не существовал, когда document.ready()
добрался до этой точки.
Я решил это с неудобным обходным решением, но мой вопрос заключается в том, что если бы я вставлял тег <script>
в загруженный контент ajax и еще один document.ready()
внутри этого, будет ли этот второй document.ready()
анализироваться ТОЛЬКО один раз Выполняется загрузка ajax? Другими словами, считает ли это, что отдельно загруженное содержимое ajax будет другим document
, и если да, имеет ли еще document.ready()
внутри того, что HTML-работа, обработанная ajax, так, как я думаю, она делает?
В качестве альтернативы; что было бы лучшим способом справиться с этой ситуацией? (необходимо подключить прослушиватель событий к элементу DOM, который еще не существует на document.ready()
)
Ответы
Ответ 1
Чтобы ответить на ваш вопрос: Нет, document.ready не будет запускаться снова после завершения запроса ajax. (Содержимое в ajax загружается в ваш документ, поэтому нет второго документа для содержимого ajax).
Чтобы решить вашу проблему, просто добавьте прослушиватель событий в элемент, где вы загружаете в него содержимое ajax.
Например:
$( "div.ajaxcontent-container" ).on( "click", "#id-of-the-element-in-the-ajax-content", function() {
console.log($( this ));
});
Для #id-of-the-element-in-the-ajax-content
вы можете использовать любой селектор, который вы использовали бы в $("selector")
. Единственное отличие состоит в том, что будут выбраны только элементы под div.ajaxcontent-container
.
Как это работает:
Пока div.ajaxcontent-container
существует все элементы (если они существуют сейчас или только в будущем), которые соответствуют селектору #id-of-the-element-in-the-ajax-content
, вызывают это событие click-event.
Ответ 2
Javascript в результате вызова ajax не будет отменен (по умолчанию) из-за безопасности. Кроме того, вы не можете напрямую привязывать событие к несуществующим элементам.
Вы можете связать событие с каким-то родителем, который существует, и сообщить ему, чтобы он его заметил:
$(document).ready(function(){
$(document).on('eventName', '#nonExistingElement', function(){ alert(1); }
// or:
$('#existingParent').on('eventName', '#nonExistingElement', function(){ alert(1); }
});
Всегда старайтесь как можно ближе подойти к элементу запуска, это предотвратит необратимый пузырь через DOM
Если у вас есть некоторые странные функции, вы можете сделать что-то вроде этого:
function bindAllDocReadyThings(){
$('#nonExistingElement').off().on('eventName', function(){ alert(1); }
// Note the .off() this time, it removes all other events to set them again
}
$(document).ready(function(){
bindAllDocReadyThings();
});
$.ajaxComplete(function(){
bindAllDocReadyThings();
});
Ответ 3
попробуйте это, это не работает, потому что ваш элемент управления еще не создан, и вы пытаетесь прикрепить событие, если вы используете его на мероприятии, оно будет работать нормально. сообщите мне, если вы столкнетесь с какими-либо проблемами.
$(document).ready(function(){
$(document).on('click', '#element', function (evt) {
alert($(this).val());
});
});
Ответ 4
Ответ здесь - делегированное событие:
JSFiddle
JSFiddle - действительно динамический
JQuery
$(document).ready(function(){
// Listen for a button within .container to get clicked because .container is not dynamic
$('.container').on('click', 'input[type="button"]', function(){
alert($(this).val());
});
// we bound the click listener to .container child elements so any buttons inside of it get noticed
$('.container').append('<input type="button" class="dynamically_added" value="button2">');
$('.container').append('<input type="button" class="dynamically_added" value="button3">');
$('.container').append('<input type="button" class="dynamically_added" value="button4">');
$('.container').append('<input type="button" class="dynamically_added" value="button5">');
});
HTML
<div class="container">
<input type="button" class="dynamically_added" value="button1">
</div>
Ответ 5
Я работаю над кодовой базой с другом, у которого есть аналогичное требование. Опция делегированного обработчика событий, безусловно, лучше всего, если вы хотите присоединить обработчики событий. Альтернативой, особенно если вам нужно выполнить другую обработку DOM в вашей функции $(document).ready
, заключается в том, чтобы поместить код, который вы хотите запустить, в элемент script в конце вашего кода. В основном, вместо:
<script type="text/javascript">
$(document).ready(function() {
// Your code here
});
</script>
<!-- rest of dynamically loaded HTML -->
Попробуйте заменить script и остальную часть HTML, чтобы у вас было:
<!-- rest of dynamically loaded HTML -->
<script type="text/javascript">
// Your code here
</script>
Это заставляет браузер обрабатывать ваш код только после того, как он загрузил каждый другой элемент DOM в динамически загружаемом HTML. Конечно, это означает, что вам нужно убедиться, что вставленный HTML не имеет непреднамеренных последствий пользовательского интерфейса, используя CSS/HTML вместо JS. Его старый трюк Javascript из прошедших лет. В качестве бонуса вам больше не нужен jQuery.
Я должен упомянуть, что в Chromium v34 размещение второго вызова $(document).ready
внутри тега <script>
в динамически загружаемом HTML кажется ожидающим загрузки динамически загружаемого DOM, а затем запускает функцию, как вы описали. Я не уверен, что это поведение является стандартным, так как это вызвало у меня большое горе при попытке автоматизировать тесты с помощью такого кода.
Ответ 6
JQuery AJAX.load() имеет встроенную функцию для обработки этого.
Вместо простого $('div#content').load('such_a_such.url');
вы должны включить функцию обратного вызова. JQuery.load() предоставляет возможность для следующего:
$('div#content').load('such_a_such.url',
{ data1: "First Data Parameter",
data2: 2,
data3: "etc" },
function(){ $('#span1').text("This function is the equivalent of");
$('#span2').text("the $(document).ready function.");
}
);
Однако вам не нужно включать аргумент данных.
$( "#result" ).load( "ajax/test.html", function() { alert ( "Загрузка выполнена" ); });
http://api.jquery.com/load/