2013-11-27 3 views
33

Вчера у меня возникла проблема, когда обработчик событий .on('click'), который я выполнял, работал неправильно. Оказывается, это потому, что я пытался применить этот .on('click') до того, как этот элемент существовал в DOM, потому что он загружался через AJAX и, следовательно, еще не существовал, когда document.ready() добрался до этой точки.Загружает ли содержимое AJAX содержимое «document.ready»?

я решил его с неловким обходным путем, но мой вопрос, если я должен был поставить <script> тег в АЯКСЕ загруженного содержимого и другой document.ready() внутри, что, был бы, что второй document.ready() быть разобран только один раз, что содержание Аякса делается быть загружен? Другими словами, он считает, что отдельно загруженное содержимое ajax должно быть другим document, и если да, то имеет ли еще document.ready() в том, что HTML-работа, обработанная ajax, так, как я думаю?

В качестве альтернативы; что было бы лучшим способом справиться с этой ситуацией? (необходимо подключить прослушиватель событий к элементу DOM, который еще не существует на document.ready())

+1

Для обработчиков событий, делегирование использование событий. Для чего-либо еще (например, для инициализации плагина) используйте функцию обратного вызова для вашего вызова AJAX. –

ответ

28

Чтобы ответить на ваш вопрос: Нет. 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 запустят этот щелчок-событие.

+1

Благодаря! Большинство ответов были одинаковыми, но ваши ответили на мой вопрос, а затем продолжили объяснение делегирования событий. Ура! –

+0

отличный ответ, мне очень помогли сегодня – Richlewis

+1

На самом деле document.ready будет вызываться в ajax-загруженном HTML. Попробуйте добавить в АЯКС загруженной страницы и вы увидите, что сообщение в журнале. Но функция.ready на главной странице не запускается после ajax .. просто чтобы быть понятным. –

10

Javascript в результате вызова ajax не будет отменен (по умолчанию) из-за безопасности. Кроме того, вы не можете напрямую привязывать событие к несуществующим элементам.
Вы может связать событие с какими-то из родителей, что действительно существует, и сказать ему, чтобы проверить его дети:

$(document).ready(function(){ 
    $(document).on('eventName', '#nonExistingElement', function(){ alert(1); } 
    // or: 
    $('#existingParent').on('eventName', '#nonExistingElement', function(){ alert(1); } 
}); 

Всегда пытается получить как можно ближе к пусковому элементу, как вы можете, это предотвратишь unnessesary бульканья через 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(); 
}); 
+0

Это не работает без ошибок, если у вас нет функций на всех загруженных страницах. Поэтому я предлагаю добавить что-то вроде '$ (document) .ajaxStart (function() {delete window.bindAllDocReadyThings;});' и скорее определить функции в документах как 'bindAllDocReadyThings = function() {...}' – Smamatti

2

Ответ здесь делегированного событие:

JSFiddle

JSFiddle - Truly dynamic

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

попробуйте это, это не работает, потому что ваш элемент управления еще не создан, и вы пытаетесь прикрепить событие, если вы используете на мероприятии, он будет работать нормально. сообщите мне, если вы столкнетесь с какими-либо проблемами.

$(document).ready(function(){ 
    $(document).on('click', '#element', function (evt) { 
     alert($(this).val()); 
    }); 
}); 
0

Я работаю над кодовой базой с другом, который имеет аналогичное требование. Опция делегированного обработчика событий, безусловно, лучше всего, если вы хотите присоединить обработчики событий. Альтернативой, особенно если вам нужно выполнить другую обработку DOM в вашей функции $(document).ready, заключается в том, чтобы поместить код, который вы хотите запустить, в элемент сценария в конце вашего кода. В принципе, вместо:

<script type="text/javascript"> 
    $(document).ready(function() { 
    // Your code here 
    }); 
</script> 
<!-- rest of dynamically loaded HTML --> 

Попробуйте поменять сценарий и остальную часть HTML вокруг так у вас есть:

<!-- rest of dynamically loaded HTML --> 
<script type="text/javascript"> 
    // Your code here 
</script> 

Это заставляет браузер обрабатывать только ваш код, как только он загружен любой другой DOM элемент в динамически загружаемом HTML. Конечно, это означает, что вам нужно убедиться, что вставленный HTML не имеет непреднамеренных последствий пользовательского интерфейса, используя CSS/HTML вместо JS. Его старый трюк Javascript из прошедших лет. В качестве бонуса вам больше не нужен jQuery.

Следует отметить, что в Chromium v34, помещая второй вызов в тег <script> в динамически загружаемом HTML, кажется, ждет загрузки динамически загружаемой DOM, а затем запускает функцию, как вы описали. Я не уверен, что это поведение является стандартным, поскольку оно вызвало у меня большое горе при попытке автоматизировать тесты с помощью такого кода.

0

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", функция() { оповещения ("Нагрузка была выполнена."); });

http://api.jquery.com/load/

Смежные вопросы