Я хочу связать событие с элементами, которые динамически создаются при вызове 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();  
    }
});
}

С какой проблемой я сталкиваюсь? Событие успешно связывается с новыми элементами, но для старых элементов или элементов, загружаемых при загрузке страницы, событие связывается дважды . В чем проблема с этим?

2
habib 21 Авг 2018 в 10:33

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.

4
31piy 21 Авг 2018 в 07:41

Вы должны отменить привязку события, которое делегировано для вашего элемента, используя метод unbind, а затем перепривязать его.

$('.myClickableElement').unbind('click').bind('click', function(){
    // action goes here
});

Если к вашему .myClickableElement уже прикреплено событие, вы удалите его, отменив привязку.

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

0
Radonirina Maminiaina 21 Авг 2018 в 07:40

Вы можете делегировать событие 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
    }
});
}
0
Bhushan Kawadkar 21 Авг 2018 в 07:39
51943743