Я хочу связать событие с элементами, которые динамически создаются при вызове ajax. Некоторые элементы уже присутствуют, и событие связывается с ними при загрузке страницы. Но когда новые элементы создаются после вызова ajax, новые элементы теряют свою привязку.
Я искал и нашел очень хорошее решение. Событие Jquery не сработает после вызова ajax
В этом вопросе «Джейсон Фингар» представил два решения, чтобы это исправить
- второе решение использует метод on, но он не будет работать для меня
- первый метод работы, но некоторые проблемы
Вот первое решение, которое он представил
«1) Инкапсулируйте ваш« обязательный »код и вызывайте его как при загрузке страницы, так и сразу после того, как соответствующий элемент будет добавлен обратно на страницу. Например:«
$(document).ready(function(){
// bind event handlers when the page loads.
bindButtonClick();
});
function bindButtonClick(){
$('.myClickableElement').click(function(){
... event handler code ...
});
}
function updateContent(){
$.ajax({
url : '/ajax-endpoint.php',
data : {'onMyWay' : 'toServer'},
dataType : 'html',
type : 'post',
success : function(responseHtml){
// .myClickableElement is replaced with new (unbound) html
element(s)
$('#container').html(responseHtml);
// re-bind event handlers to '.myClickableElement'
bindButtonClick();
}
});
}
С какой проблемой я сталкиваюсь? Событие успешно связывается с новыми элементами, но для старых элементов или элементов, загружаемых при загрузке страницы, событие связывается дважды . В чем проблема с этим?
3 ответа
JQuery не проверяет, связан ли прослушиватель событий с элементом, прежде чем связывать прослушиватель для того же события. В вашем коде .myClickableElement
выбирает все такие элементы, а для существующих элементов будут добавлены дубликаты слушателей.
Открепив слушателей события первым
Один из способов исправить это - сначала удалить слушателя, а затем снова связать его. Таким образом, он будет существовать один раз для каждого целевого элемента.
function bindButtonClick(){
$('.myClickableElement').off('click').on('click', function(){
... event handler code ...
});
}
Используя делегирование события на родительский элемент
Другой (но эффективный) способ - использовать делегирование событий для дочерних элементов. Я мало что знаю о вашем HTML, но вы можете сделать это на родительском элементе (здесь .parent
является родителем для всех .myClickableElement
элементов):
$('.parent').on('click', '.myClickableElement', function() {
... event handler code ...
});
Это включит привязку событий для тех элементов, которых нет в DOM при выполнении этого кода. Так что это будет общее решение для вашей проблемы, и вам не нужно будет привязывать слушателей, когда завершится AJAX.
Вы должны отменить привязку события, которое делегировано для вашего элемента, используя метод unbind, а затем перепривязать его.
$('.myClickableElement').unbind('click').bind('click', function(){
// action goes here
});
Если к вашему .myClickableElement
уже прикреплено событие, вы удалите его, отменив привязку.
Чтобы лучше понять, ознакомьтесь с этой документацией.
Вы можете делегировать событие cilck, используя document.on
или родительский контейнер, который будет применим как к существующим, так и к динамически создаваемым элементам, и нет необходимости связывать его снова и снова изнутри вызова ajax
$(document).ready(function(){
// If you know that elements for which click handler required can be anywhere in the document
/*$(document).on('click', '.myClickableElement', function(){
... event handler code ...
});*/
//If you are sure that elements to which click event handler required is belongs to container elements
$('#container').on('click', '.myClickableElement', function(){
... event handler code ...
});
});
function updateContent(){
$.ajax({
url : '/ajax-endpoint.php',
data : {'onMyWay' : 'toServer'},
dataType : 'html',
type : 'post',
success : function(responseHtml){
// .myClickableElement is replaced with new (unbound) html
element(s)
$('#container').html(responseHtml);
// re-bind event handlers to '.myClickableElement'
//bindButtonClick(); -- not required to bind again
}
});
}
Похожие вопросы
Связанные вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.