Некорректно работает AJAX пагинация

94
22 марта 2022, 12:50

Всем привет

На сайте есть пагинация к статьям, которая работает следующим образом: пользователь нажимает кнопку 'Показать больше статей', после чего добавляется еще N постов. У каждой отдельной статьи есть кнопка 'Добавить в избранное', которая тоже работает на AJAX. Суть проблемы в том, что когда оба аякса подключены(пагинация и избранное), после нажатии на клавишу пагинации, у всех ново загруженных постов не работает кнопка 'добавить в избранное' и плюс ко всему, эти посты дублируются.

По отдельности оба аякса работают замечательно, как и должны.В чем собственно может быть проблема? Из-за чего все так происходит.

ajax пагинация:

function ajaxPagination()
{
    $('#pagination a.page-link').each((index, el) =>{
        $(el).click((e) => {
            e.preventDefault()
            let page_url = $(el).attr('href')
            console.log(page_url)
            $.ajax({
                url: page_url,
                type: 'GET',
                success: (data) => {
                    $('.do_it').append( $(data).filter('.do_it').html())
                    $('.pagination').empty()
                    $('.pagination').append( $(data).find('.pagination').html())
                }
            })
        })
    })
}
$(document).ready(function() {
    ajaxPagination()
})
$(document).ajaxStop(function() {
    ajaxPagination()
})

ajax избранное:

const add_to_favorites_url = '/favorites/add/';
const remove_from_favorites_url = '/favorites/remove/';
const favorites_api_url = '/favorites/api/';
const added_to_favorites_class = 'added';

function add_to_favorites(){
    $('.add-to-favorites').each((index, el) => {
        $(el).click((e) => {
            e.preventDefault()
            const type = $(el).data('type');
            const id = $(el).data('id');
            if( $(e.target).hasClass(added_to_favorites_class) ) {
                $.ajax({
                    url: remove_from_favorites_url,
                    type: 'POST',
                    dataType: 'json',
                    data: {
                        type: type,
                        id: id,
                    },
                    success: (data) => {
                        $(el).removeClass(added_to_favorites_class)
                    }
                })
            } else {
                $.ajax({
                    url: add_to_favorites_url,
                    type: 'POST',
                    dataType: 'json',
                    data:{
                        type: type,
                        id: id,
                    },
                    success: (data) => {
                        $(el).addClass(added_to_favorites_class)
                        // get_session_favorites_statistics()
                    }
                })
            };
        })
    })
};

function get_session_favorites() {
    // get_session_favorites_statistics()
    $.getJSON(favorites_api_url, (json) => {
        if (json !== null) {
            for (let i = 0; i < json.length; i++) {
                $('.add-to-favorites').each((index, el) => {
                    const type = $(el).data('type')
                    const id = $(el).data('id')
                    if ( json[i].type == type && json[i].id == id ){
                        $(el).addClass(added_to_favorites_class)
                    }
                })
            }
        }
    })
}
$(document).ready(function() {
    add_to_favorites()
    get_session_favorites()
})
Answer 1

Проблема в реализации add_to_favorites:

$('.add-to-favorites').each((index, el) => {
    $(el).click((e) => {

навешивает обработчик событий на каждый элемент отдельно; соответственно, не навешивает на те, которые ещё не подгрузили и на них надо было бы навешивать отдельно. К счастью, есть более грамотный подход, называемый делегированием обработчиков. Суть такая: обработчик навешивается на родителя, который смотрит, кликнули ли в .add-to-favorites, и обрабатывает клик так, будто обработчик был привязан непосредственно к .add-to-favorites. jQuery умеет такое "из коробки":

$('body').on('click', '.add-to-favorites', (e) => {

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

READ ALSO
Блок &quot;Поделиться&quot; от Яндекс не отображается

Блок "Поделиться" от Яндекс не отображается

Блок установлен при помощи кода:

141
Как сверстать многоуровневое меню?

Как сверстать многоуровневое меню?

Как сверстать такое многоуровневое меню?

209
Получить текущий url iframe?

Получить текущий url iframe?

Возможно ли и как получить текущий url iframe ( отличный от начального src ) ?

64