我正在使用Isotope Layout来组织一系列的div,我已经分别成功地使AJAX负载增加了,并且使AJAX过滤器成功了,但是我想将两者结合起来。
从本质上讲,您可以加载更多,但是如果选择过滤器,则按“加载更多”只会在该过滤器上加载更多。
我的方法如下:
代码实现:
load-more.js
/**
* Load more script using AJAX
*/
jQuery(document).ready(function ($) {
let has_run = false;
// Hook into click event
$('button.load-more-posts').click(function (e) {
e.preventDefault();
let button = $(this);
let nonce = $(this).data("nonce");
let $grid = $('#grid').isotope({
itemSelector: '.grid-item',
});
// Disable the button
button.prop("disabled", true);
// Check the offset
if (has_run == false) {
button.data('current-page', $(this).data("current-page"));
}
// Perform AJAX request
$.ajax({
type: 'POST',
dataType: 'json',
url: ajax_load_more_object.ajax_url,
data: {
action: 'ajax_load_more_posts',
security: nonce,
current_page: button.data('current-page'),
},
beforeSend: function (xhr) {
button.text('Fetching...');
},
success: function (response) {
if (response) {
button.text('Load more');
// An array to store new items added via AJAX
var new_items = [];
// Run through JSON
$.each(response, function (key, value) {
var $new_item =
$(`<div class="grid-item article-post-card ${value.category[0]['slug']}">
<a class="article-post-card__anchor" href=" ${value.permalink}" alt="${value.title}">
<div class="article-post-card__featured-image-container">
<div class="article-post-card__overlay"></div>
<div class="article-post-card__featured-image">
${value.thumbnail}
</div>
<div class="article-post-card__category-label">
${value.category[0]['name']}
</div>
</div>
<div class="article-post-card__content-wrapper">
<div class="article-post-card__publish-date">
<time class="updated" datetime="${value.post_time}">${value.date}</time>
</div>
<div class="article-post-card__title">
${value.title}
</div>
<div class="article-post-card__excerpt">
${value.introduction}
</div>
</div>
</a>
</div>`);
new_items.push($new_item[0]);
});
// Add the new items to the grid
$grid
.isotope('insert', new_items)
.imagesLoaded().progress(function () {
$grid.isotope('layout');
});
// Set the current page to the next page
var current_page = button.data("current-page");
var max_pages = button.data("max-pages");
button.data("current-page", current_page + 1);
if (current_page >= max_pages) {
button.text("No more posts to load");
} else {
// Undo Button Disable
button.prop("disabled", false);
}
// Update boolean so that page count is not reset
has_run = true;
// Return false as we're at the end
return false;
// If the AJAX function returned no data
} else {
button.remove();
}
},
error: function (xhr, status, error) {
console.log("There was an error", error);
}
});
});
});
load-more.php
function ajax_load_more_posts_callback()
{
// First check the nonce, if it fails the function will break
check_ajax_referer('ajax_load_more_posts', 'security');
// Get the data we have from the load more button
$current_page = $_POST['current_page'];
if ($current_page != null && absint($current_page)) {
// Finally, we'll set the query arguments and instantiate WP_Query
$args = array(
'post_type' => 'post',
'status' => 'published',
'orderby' => 'post_date',
'order' => 'DESC',
'paged' => $current_page
);
$query = new WP_Query($args);
$post_list = array();
if ($query->have_posts()) :
while ($query->have_posts()) : $query->the_post();
$introduction = !get_field('introduction') ? get_the_excerpt() : get_field('introduction');
$post_list[] = array(
'category' => get_the_category(),
'tags' => get_the_tags(),
'title' => get_the_title(),
'introduction' => $introduction,
'post_time' => get_post_time('c', true),
'date' => get_the_date(),
'permalink' => get_permalink(),
'thumbnail' => get_the_post_thumbnail(),
);
endwhile;
endif;
echo json_encode($post_list);
wp_die();
}
}
get-posts.js
/**
* The selectable filters
*/
let $filters = $('.filters input');
let $resultCount = $('.filter-box__result-count');
// Inititialize Isotope
const $grid = $('#grid').isotope({
itemSelector: '.grid-item',
percentagePosition: true,
animationEngine: 'best-available',
animationOptions: {
duration: 800,
},
filter: '*',
masonry: {
columnWidth: '.grid-item',
gutter: 30,
},
})
// The items in the grid
const $items = $grid.data('isotope');
/**
* Each time an image is loaded, re-layout the grid.
* This prevents any weird overlapping.
*/
$grid.imagesLoaded().progress(function () {
$grid.isotope('layout');
});
/**
* Apply filters to Isotope when any filters are updated.
* This will also update the result count and add some block elements.
*/
$filters.change(function () {
// An empty array to contain filters
let $selectedFilters = [];
// Loop through filters and add values if checked
$('.filters input').each(function (counter, element) {
if (element.checked) {
$selectedFilters.push(element.value);
}
})
console.log($selectedFilters);
// If there are filters in the filters array, join them
if ($selectedFilters.length > 0) {
$('.filter-box__applied-filters-area').show();
$filters = $selectedFilters.join(', ');
} else {
$filters = '*';
}
// Perform AJAX request
$.ajax({
type: 'POST',
dataType: 'json',
url: ajax_get_posts_object.ajax_url,
data: {
action: 'ajax_get_posts',
filters: $selectedFilters,
},
beforeSend: function (xhr) {
console.log('Retreiving');
},
success: function (response) {
if (response) {
// An array to store new items added via AJAX
var new_items = [];
// Run through JSON
$.each(response.posts, function (key, value) {
console.log(value);
var $new_item =
$(`<div class="grid-item article-post-card ${value.category[0]['slug']}">
<a class="article-post-card__anchor" href=" ${value.permalink}" alt="${value.title}">
<div class="article-post-card__featured-image-container">
<div class="article-post-card__overlay"></div>
<div class="article-post-card__featured-image">
${value.thumbnail}
</div>
<div class="article-post-card__category-label">
${value.category[0]['name']}
</div>
</div>
<div class="article-post-card__content-wrapper">
<div class="article-post-card__publish-date">
<time class="updated" datetime="${value.post_time}">${value.date}</time>
</div>
<div class="article-post-card__title">
${value.title}
</div>
<div class="article-post-card__excerpt">
${value.introduction}
</div>
</div>
</a>
</div>`);
new_items.push($new_item[0]);
});
console.log(response.pages);
console.log(response.current);
$grid.isotope('remove', $grid.isotope('getItemElements'));
$grid.isotope({
filter: $filters
})
.isotope('insert', new_items)
.imagesLoaded().progress(function () {
$grid.isotope('layout');
});
updateFilterCount();
// Return false as we're at the end
return false;
// If the AJAX function returned no data
} else {}
},
error: function (xhr, status, error) {
console.log("There was an error", error);
}
});
});
get-posts.php
function ajax_get_posts_callback()
{
$filters = $_POST['filters'] ?? '';
$filter_string = join(",", $filters);
$args = array(
'post_type' => 'post',
'status' => 'published',
'category_name' => $filter_string,
'orderby' => 'post_date',
'order' => 'DESC',
);
$query = new WP_Query($args);
$post_list = array();
if ($query->have_posts()) :
$pages = $query->max_num_pages;
while ($query->have_posts()) : $query->the_post();
$introduction = !get_field('introduction') ? get_the_excerpt() : get_field('introduction');
$post_list[] = array(
'category' => get_the_category(),
'tags' => get_the_tags(),
'title' => get_the_title(),
'introduction' => $introduction,
'post_time' => get_post_time('c', true),
'date' => get_the_date(),
'permalink' => get_permalink(),
'thumbnail' => get_the_post_thumbnail(),
);
endwhile;
endif;
$data = [
'posts' => $post_list,
'pages' => $pages,
'current' => 1
];
echo json_encode($data);
wp_die();
}
基本上,我需要一种方法来传递选定的类别,以便在发生过滤时加载更多内容。