Внедрить HTML с помощью jQuery closest() и Ajax

#jquery #ajax #closest

Вопрос:

У меня есть список, в котором каждый элемент может отображать свое содержимое, вводя его с помощью Ajax.

 (function($) {
    $(document).ready(function() {

        $('.show-content').click(function() {
            
            var post_id = $(this).closest('article').attr('data-post-id');

            // ↓ Works. Target the .content <div> in the single <li>.
            $(this).closest('li').find('.content').prepend('<div class="loader">Loading...</div>'); 
            
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    'action': 'load_loop_content',
                    'post_id': post_id
                }
            }).done(function(response) {

                // ↓ Does not work, the button stay displayed.
                $(this).hide(); // Hide Button
                // ↓ Work, but hide the button in all <li>.
                // $('.show-content').hide(); // Hide Button

                // ↓ Works only using $('.content').html(response) and has been injected into all <li>.
                $(this).closest('li').find('.loader').hide(); // Hide Loader

                // ↓ Does not work, nothing happens and the message "Loading ..." is still displayed.
                $(this).closest('li').find('.content').html(response); // Inject Content
                // ↓ Works, but inject the post content in all <li>.
                // $('.content').html(response);

            });

        });
        
    });
})(jQuery);
 

Но , используя closest() , это больше не работает. Я изложил подробности в комментариях к коду.

Есть какие-нибудь идеи, откуда берется проблема?

Комментарии:

1. this это другое значение, а не элемент в обратном .done вызове. this меняется от функции к функции. Видеть this

Ответ №1:

Просто сохраните свой контент в константе и используйте его впоследствии

 (function($) {
$(document).ready(function() {

    $('.show-content').click(function() {

        const myButton = $(this);
        var post_id = myButton.closest('article').attr('data-post-id');

        // ↓ Works. Target the .content <div> in the single <li>.
        const myContent = myButton.closest('li').find('.content');
        myContent.prepend('<div class="loader">Loading...</div>'); 
        
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                'action': 'load_loop_content',
                'post_id': post_id
            }
        }).done(function(response) {

            myButton.hide(); // Hide Button
            myContent.html(response);

        });

    });
    
});
})(jQuery);
 

Комментарии:

1. Большое вам спасибо! это работает очень хорошо. По крайней мере, я узнал, что мои вещи должны храниться в const.