Bước 1: Register jquery
<?php add_action('wp_enqueue_scripts', 'enqueue_infinite_scroll_scripts'); function enqueue_infinite_scroll_scripts(){ if ( !is_shop() && !is_product_taxonomy() ) { return; } global $wp_query; wp_enqueue_script( 'infinite-scroll', THEME_URL . '/assets/js/infinite-scroll.js', ['jquery'], '1.0', true ); wp_localize_script('infinite-scroll', 'lmproduct_obj', [ 'ajax_url' => admin_url('admin-ajax.php'), 'query_vars' => json_encode($wp_query->query_vars), 'nonce' => wp_create_nonce( 'lmp_check_nonce' ), 'max_num_pages' => $wp_query->max_num_pages, ]); } ?>
trong file infinite-scroll.js thêm đoạn code sau:
jQuery(document).ready(function ($) { var canLoad = true; var page = 2; // Load more product function loadMoreProducts() { if (typeof lmproduct_obj !== 'undefined') { const maxPages = parseInt(lmproduct_obj.max_num_pages); if (!canLoad || page > maxPages) return; canLoad = false; // Ngăn tải lặp lại $('.lmproduct-loading').addClass('is-loading'); $.ajax({ url: lmproduct_obj.ajax_url, type: 'POST', data: { action: 'load_more_products', page: page, nonce: lmproduct_obj.nonce, query_vars: lmproduct_obj.query_vars, }, success: function (response) { if (response.success && response.data) { $('.products').append(response.data); // Append new product page++; canLoad = true; // allow load more $('.lmproduct-loading').removeClass('is-loading'); } // last page if (page > maxPages) { canLoad = false; $('.lmproduct-loading').remove(); } }, error: function () { $('.lmproduct-loading').removeClass('is-loading'); canLoad = true; }, }); } } // Use Intersection Observer to detect when lmproduct-loading enters the viewport const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { loadMoreProducts(); // Load more products when element appears } }); }, { root: null, rootMargin: '0px', threshold: 0.1 } // 10% of the elements appear ); // Theo dõi phần tử lmproduct-loading const loadingElement = document.querySelector('.lmproduct-loading'); if (loadingElement) { observer.observe(loadingElement); } });
Bước 2: Remove default pagination
remove_action( 'woocommerce_after_shop_loop', 'woocommerce_pagination', 10 ); add_action( 'woocommerce_after_shop_loop', 'show_load_more_product_loading' ); function show_load_more_product_loading(){ global $wp_query; if( $wp_query->max_num_pages > 1 ){ echo '<div class="lds-ellipsis lmproduct-loading"><div></div><div></div><div></div><div></div></div>'; } }
Bước 3: Handle ajax loadmore product
function handle_load_more_products() { // phpcs:disable WordPress.Security.NonceVerification.Missing if ( !isset( $_POST['nonce'] ) ) { wp_send_json_error( 'missing_fields' ); wp_die(); } // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if( !wp_verify_nonce( wp_unslash( $_POST['nonce'] ), 'lmp_check_nonce' ) ){ wp_send_json_error( 'bad_nonce' ); wp_die(); } $page = isset($_POST['page']) ? absint($_POST['page']) : 1; $query_vars = isset($_POST['query_vars']) ? json_decode(stripslashes($_POST['query_vars']), true) : []; $query_vars['paged'] = $page; $query_vars['post_status'] = 'publish'; $products = new WP_Query($query_vars); if ($products->have_posts()) { ob_start(); while ($products->have_posts()) { $products->the_post(); wc_get_template_part('content', 'product'); } wp_reset_postdata(); wp_send_json_success(ob_get_clean()); } else { wp_send_json_error('No more products'); } wp_die(); } add_action('wp_ajax_load_more_products', 'handle_load_more_products'); add_action('wp_ajax_nopriv_load_more_products', 'handle_load_more_products');