简体   繁体   中英

Istotope ajax content load

I'm stuck implementing load next set of posts in WordPress with isotope masonry layout. It's just not triggered for appended elements and I can't figure out why. If someone could point me in right direction I would appreciate.

jQuery AJAX function

function load_content( args ) {

        $container = $('#container-async');
        $status    = $('.status');

        $.ajax({
            url: ajax_url,
            data: {
                action: 'do_load_posts',
                nonce: nonce,
                args: args
            },
            type: 'post',
            dataType: 'json',
            success: function( data, textStatus, XMLHttpRequest ) {

                $items = data.posts;

                if ( args.action === 'filter') {
                    /**
                     * Replace items
                     */
                    $container.imagesLoaded( function() {
                        $container.isotope({
                            itemSelector: '.grid-item',
                            percentPosition: true,
                            masonry: {
                                columnWidth: '.grid-sizer'
                            }
                        });
                        $container.html( $items ).isotope( 'appended', $items, function() {
                            console.log('inserted');
                        });
                    });
                }
                else {
                    /**
                     * Append items
                     */
                    $container.imagesLoaded( function() {
                        $container.isotope({
                            itemSelector: '.grid-item',
                            percentPosition: true,
                            masonry: {
                                columnWidth: '.grid-sizer'
                            }
                        });
                        $container.append( $items ).isotope( 'appended', $items, function() {
                            console.log('appended');
                        });
                    });
                }
            },
            error: function( MLHttpRequest, textStatus, errorThrown ) {
                $status.toggleClass('active');
            }
        });
}

WordPress AJAX:

function ajax_do_load_posts() {

    // Verify nonce
    if( !isset( $_POST['nonce'] ) || !wp_verify_nonce( $_POST['nonce'], 'nonce' ) )
        die('Permission denied');

    $response = [
        'status' => 500,
        'posts'  => 0,
    ];

    $filter = $_POST['args'];

    $type   = get_post_type_object( $filter['type'] );
    $args   = [
        'post_type'      => sanitize_text_field($filter['type']),
        'paged'          => intval($filter['page']),
        'posts_per_page' => $filter['qty'],
    ];

    $qry = new WP_Query($args);

    if ($qry->have_posts()) :
        ob_start();

        while($qry->have_posts()) : $qry->the_post(); ?>
            <div class="grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3">
                <?php get_template_part('templates/loop', 'card' ); ?>
            </div>
        <?php endwhile;

        $response = [
            'status' => 200,
            'posts'  => ob_get_clean(),
        ];
    endif;

    wp_reset_query();
    wp_reset_postdata();

    die(json_encode($response));
}

add_action('wp_ajax_do_load_posts', 'ajax_do_load_posts');
add_action('wp_ajax_nopriv_do_load_posts', 'ajax_do_load_posts');

Items are inserted or appended into container but masonry is triggered only on items that are already there on page load.

在此处输入图片说明

I have googled around and tried various solutions but none of them work, neither with isotope or masonry jquery plugin.

I was able to fix my issue, and kind of looks like the problem is because I was using jQuery default append/insert methods. I have switched to isotope methods and now things look fine.

So basically instead of

$container.html( $items ).isotope( 'appended', $items, function() {
    console.log('inserted');
});

I am now using:

$grid.isotope('insert', jQuery($items));

It looks logical actually that isotope cannot know items are appended if I don't use isotopes append/insert method. And notice that I also wrapped $items inside jQuery.

Anyhow my working JS for same PHP function is:

function load_content( args ) {

    $container = $('#container-async');
    $status    = $('.status');

    $.ajax({
        url: ajax_url,
        data: {
            action: 'do_load_posts',
            nonce: nonce,
            args: args
        },
        type: 'post',
        dataType: 'json',
        success: function( data, textStatus, XMLHttpRequest ) {

            $items = data.posts;

            var $grid = $('.masonry').imagesLoaded( function() {

                $grid.isotope({
                    itemSelector: '.grid-item',
                    percentPosition: true,
                    masonry: {
                        columnWidth: '.grid-sizer'
                    }
                });

                if ( args.action === 'filter') {
                    $grid.isotope('remove', $('.grid-item'));
                }

                $grid.isotope('insert', jQuery($items));
            });


            $grid.on( 'layoutComplete', function( event, laidOutItems ) {
                $container.removeClass(data.action);
            });
        },
        error: function( MLHttpRequest, textStatus, errorThrown ) {
            $status.toggleClass('active');
        }
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM