Выполнение функции jquery.on с загруженным контентом AJAX
У меня возникла проблема с получением функции .on 'click' для работы с загруженным контентом AJAX.
Я работал с jquery.live раньше, но это первый раз с .on и понимаем, что он работает точно так же, поэтому не уверен, почему у меня возникают проблемы.
Ниже приведен HTML, который дает элемент, на который вы нажимаете
<h1>Press & Media</h1>
<div id="back"></div>
<div id="overlay-content">
<span id="edocs" class="tab"></span>
<span id="news" class="tab"></span>
<span id="partners" class="tab"></span>
</div>
Ниже приведена функция, которая загружает содержимое AJAX.
$("#overlay-content").on('click','#news',function() {
var active = 1;
$("#loading").show();
$("#overlay-content").fadeOut(1000, function() {
$.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
$("#loading").hide(400);
$("#overlay-content").empty().append(data).fadeIn(1000);
});
});
});
Это должно загрузить следующий HTML
<div id="news-left-panel">
<h4>News Section</h4>
<ul>
<li id="newsID2" class="newsYear">
<p>2012</p>
<ul class="newsMonths" style="display:none">
<li>Jan
<ul class="newsArticles" style="display:none">
<li onClick="newsID(2)">test</li>
</ul>
</li>
<li>Feb</li>
<li>Mar</li>
</ul>
</li>
<li id="newsID1" class="newsYear">
<p>2011</p>
<ul class="newsMonths" style="display:none">
<li>Dec
<ul class="newsArticles" style="display:none">
<li onClick="newsID(1)">Test</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Теперь приведенный выше код просто не выполнится, покажет какие-либо ошибки и т.д. в firebug.
Итак, я немного потерял, почему это не выполняется, предупреждение() даже не выполняется.
Ответы
Ответ 1
Сначала убедитесь, что вы попали в цель, попробуйте это и посмотрите, отображается ли предупреждение:
$(function() {
$(document).on('click', '#news', function() {
alert('ok');
});
});
Если предупреждение появляется при нажатии на элемент #news, это нормально.
Теперь в эту строку:
$.get("http://<? echo ROOT; ?>includes/functions.php",
Вы используете сокращенное открытие PHP, и его нужно включить, вы можете попробовать
<?php echo ROOT; ?>
Но что такое frack ROOT, он никогда не видел этого раньше и не нашел ничего в руководстве PHP по ROOT, поэтому я попробовал на своем собственном сервере с новейшей версией PHP и получил ошибку, так как ROOT не существует, вместо этого он предположил, что это была строка и только эхо-сигнал "ROOT", поэтому ваша ссылка будет выглядеть так:
$.get("http://ROOTincludes/functions.php",
Это переменная, которую вы определили где-то самостоятельно, она должна начинаться с доллара, если это вы определили с помощью define()
, убедитесь, что она настроена правильно и если она использует что-то вроде $_SERVER['DOCUMENT_ROOT'];
, что не всегда что-то, что вы можете получить в javascript, поскольку обычно это папка, которая выше вашего веб-сайта, и не может быть доступна на клиентском компьютере, но только на сервере.
Также, как вы его написали, начиная с http://
, это должно быть доменное имя.
Попробуйте открыть источник просмотра в своем браузере и найти свою функцию ajax и посмотреть, что ROOT действительно выдает, так как окончательный вывод будет видимым в источнике, и если он будет установлен с помощью define() в включенном файле конфигурации и т.д., Вы увидите, что это был настроен правильно.
Ваш javascript также должен быть внутри файла PHP для выполнения PHP, или вам придется изменить настройку сервера для запуска файлов JS через PHP.
По-моему, просто использовать путь и имя файла - это правильный способ сделать это, попробуйте это и обратите внимание на консоль (F12):
$(document).on('click','#news',function() {
var active = 1;
var XHR = $.ajax({
type: 'GET',
url : '/actualpath/includes/functions.php',
data: { pressmediaNews: active }
}).done(function(data) {
console.log(data);
}).fail(function(e1, e2, e3) {
console.log('error : '+e1+' - '+e2+' - '+e3);
});
$("#loading").show();
$("#overlay-content").fadeOut(1000, function() {
XHR.done(function(data) {
$("#overlay-content").empty().append(data).fadeIn(1000);
$("#loading").hide(400);
});
});
});
Ответ 2
Используйте делегат:
$('#overlay-content').on('click', '#newsID2', function() { });
Это свяжет событие на #overlay-content
и проверяет наличие пузырьковых событий, если они возникли из #newsID2
.
В качестве примечания: у вас есть опечатка в обработчике событий (chikdren
должна быть children
), и вам действительно нужно избавиться от этого уродливого события onClick
.
Ответ 3
Должно быть больше похоже:
$("#overlay-content").on('click', '#newsID2', function() {
....
});
Или другими словами:
$('.wrapper').on('event', '.target', function() {
...
});
Где .wrapper
- это элемент, который уже существует (или документ), а .target
- это элемент внутри оболочки, в которую вы хотите запустить событие.
Функция live
в основном эквивалентна:
$(document).on('event', '.target', function() {
...
});
Ответ 4
http://bugs.jquery.com/ticket/11203
Ключевое предложение
Если на страницу вводится новый HTML-код, выберите элементы и присоединить обработчики событий после того, как новый HTML помещен на страницу.
Чтобы работать с этим сценарием, попробуйте привязать объект документа к параметру селектора:
$(document).on('click','#news',function() {...}
Ответ 5
Поскольку вы сказали, что ранее работаете с .live(), может возникнуть проблема в том, что вы пытаетесь привязать свой клик к тому, что вы добавляете к документу, прежде чем добавить его?
Когда вы используете live, он обрабатывает такие вещи автоматически, но когда вы не используете live, вещи обычно должны существовать на странице, прежде чем связывать с ними какие-либо события. Если вы добавите что-то с AJAX, вы не сможете настроить события click для этих вещей, прежде чем загружать их с помощью AJAX. Когда вы используете .live(), вы можете сделать это заблаговременно.
Я бы сделал это следующим образом:
$("#overlay-content").on('click','#news',function() {
var active = 1;
$("#loading").show();
$("#overlay-content").fadeOut(1000, function() {
$.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
$("#loading").hide(400);
$("#overlay-content").empty().append(data).fadeIn(1000);
//put your delegate/call/function,etc here
});
});
});
Ответ 6
Новости левой панели
year_Month_newsID Ваш год новостей, месяц, идентификатор новостей. Например 2012_5_16, 2012_5_17 и т.д.
<div id="news-left-panel">
<h4>News Section</h4>
<ul>
<li id="newsID2" class="newsYear">
<p>2012</p>
<ul class="newsMonths" style="display:none">
<li>Jan
<ul class="newsArticles" style="display:none">
<li id="year_Month_newsID">test</li>
</ul>
</li>
<li>Feb</li>
<li>Mar</li>
</ul>
</li>
<li id="newsID1" class="newsYear">
<p>2011</p>
<ul class="newsMonths" style="display:none">
<li>Dec
<ul class="newsArticles" style="display:none">
<li id="year_Month_newsID">Test</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Функция JQuery
$("#news-left-panel ul li").live("click", function(event) {
var news=(this.id).split("_");
var year=news[0];
var month=news[1];
var newsID =news[2];
$.ajax({
type: "POST",
url: 'http://<? echo ROOT; ?>includes/functions.php',
data: {
year: year,month:month,newsID :newsID
},
error: function(){
$('#news').html( "<p>Page Not Found!!</p>" );
// Here Loader animation
},
beforeSend: function(){
// Here Loader animation
$("#news").html('');
},
success: function(data) {
$('#news').html(data);
}
});
});
Ответ 7
Вы уверены, что ваш вызов Ajax верен/возвращает правильный HTML?
Я заменил $.get() на setTimeout() (и упрощен немного) здесь: http://jsfiddle.net/q23st/
Кажется, что работает, поэтому я подозреваю, что ваш $.get() не возвращает ожидаемое возвращение.