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');