我有一个关于当前项目的页面,在该页面中,我成功设置了AJAX帖子过滤,因此用户可以单击复选框并按对应的类别过滤帖子。我还成功地设置了AJAX帖子加载,用户可以滚动到底部,加载更多帖子。我将描述我的问题,然后发布我的代码。
My Problem
当AJAX滚动加载新帖子时,它们不在正确的类别(或类别,取决于单击的复选框)。此外,我将其设置为一次加载9篇新帖子,而他们每次只是重复相同的9篇帖子。
My Code
在我的功能中。php文件,我有以下代码:
// Setup AJAX for filter posts by category and for load more button
function ajax_filter_posts_scripts() {
// Enqueue script
wp_register_script(\'afp_script\', get_stylesheet_directory_uri() . \'/js/ajax-filter-posts.js\', false, null, false);
wp_enqueue_script(\'afp_script\');
global $wp_query;
wp_localize_script( \'afp_script\', \'afp_vars\', array(
\'afp_ajax_url\' => admin_url( \'admin-ajax.php\' ),
\'posts\' => json_encode( $wp_query->query_vars ), // everything about your loop is here
\'current_page\' => get_query_var( \'paged\' ) ? get_query_var(\'paged\') : 1,
\'max_page\' => $wp_query->max_num_pages
)
);
}
add_action(\'wp_enqueue_scripts\', \'ajax_filter_posts_scripts\', 100);
// Filter posts by category
function prefix_load_cat_posts () {
$cat_id = $_POST[\'category__in\'];
$args = array (
\'post_type\' => \'post\',
\'post_status\' => \'publish\',
\'category__in\' => $cat_id,
\'posts_per_page\' => 9,
\'orderby\' => \'date\',
\'order\' => \'DESC\',
);
$filter_posts = new WP_Query($args);
ob_start ();
if ( $filter_posts->have_posts() ) : while ( $filter_posts->have_posts() ) : $filter_posts->the_post(); ?>
<article class="article-card">
<header class="card-header">
<div class="card-img" style="background: url(\'<?php echo the_post_thumbnail_url( \'small\' ); ?>\') no-repeat center center; width: 100%; background-size: cover;"></div>
<?php the_title( "<h4 class=\'article-title\'>", "</h4>" ) ?>
<p class="article-author">By
<?php the_author(); ?>
</p>
</header>
<div class="card-content">
<p>
<?php echo wp_trim_words(get_post_meta(get_the_ID(), \'_yoast_wpseo_metadesc\', true), 15, \'...\'); ?>
</p>
</div>
<footer class="card-footer">
<a href="<?php the_permalink(); ?>" class="btn btn-article" role="button">Read Now</a>
</footer>
</article>
<?php $post_count = $filter_posts->current_post + 1; ?>
<?php if ($post_count % 3 == 0): ?>
<div class="ad-wrapper">
<?php the_ad(202070); ?>
</div>
<?php
endif;
endwhile; endif;
wp_reset_postdata();
$response = ob_get_contents();
ob_end_clean();
echo $response;
die(1);
}
add_action( \'wp_ajax_nopriv_load-filter\', \'prefix_load_cat_posts\' );
add_action( \'wp_ajax_load-filter\', \'prefix_load_cat_posts\' );
// AJAX Load More
function afp_load_more() {
$args = isset( $_POST[\'query\'] ) ? array_map( \'esc_attr\', $_POST[\'query\'] ) : array();
$args[\'post_type\'] = isset( $args[\'post_type\'] ) ? esc_attr( $args[\'post_type\'] ) : \'post\';
$args[\'paged\'] = esc_attr( $_POST[\'page\'] );
$args[\'post_status\'] = \'publish\';
$args[\'category__in\'] = $cat_id;
$args[\'order\'] = \'DESC\';
$args[\'orderby\'] = \'date\';
$args[\'offset\'] = 9;
$args[\'posts_per_page\'] = 9;
var_dump($args);
ob_start();
$loop = new WP_Query( $args );
if( $loop->have_posts() ): while( $loop->have_posts() ): $loop->the_post();
?>
<article class="article-card">
<header class="card-header">
<div class="card-img" style="background: url(\'<?php echo the_post_thumbnail_url( \'small\' ); ?>\') no-repeat center center; width: 100%; background-size: cover;"></div>
<?php the_title( "<h4 class=\'article-title\'>", "</h4>" ) ?>
<p class="article-author">By
<?php the_author(); ?>
</p>
</header>
<div class="card-content">
<p>
<?php echo wp_trim_words(get_post_meta(get_the_ID(), \'_yoast_wpseo_metadesc\', true), 15, \'...\'); ?>
</p>
<p><?php $category = get_the_category(); echo $category[0]->cat_name; ?></p>
</div>
<footer class="card-footer">
<a href="<?php the_permalink(); ?>" class="btn btn-article" role="button">Read Now</a>
</footer>
</article>
<?php $post_count = $loop->current_post + 1; ?>
<?php if ($post_count % 3 == 0): ?>
<div class="ad-wrapper">
<?php the_ad(202070); ?>
</div>
<?php
endif;
endwhile; endif; wp_reset_postdata();
$res = ob_get_contents();
ob_end_clean();
echo $res;
wp_die();
}
add_action( \'wp_ajax_afp_load_more\', \'afp_load_more\' );
add_action( \'wp_ajax_nopriv_afp_load_more\', \'afp_load_more\' );
在我的JavaScript文件中,我有以下代码:
// AJAX Post Filter scripts
var $checkbox = $("#filter input:checkbox");
let categoryIDs = [];
$checkbox.change((e) => {
let value = Number(e.currentTarget.value);
if ($checkbox.is(\':checked\')) {
categoryIDs.indexOf(value) === -1 ? (
categoryIDs.push(value)
) : (
categoryIDs = categoryIDs.filter((item) => item !== value)
)
} else {
categoryIDs = [3, 4, 28, 35, 353];
// TODO: move this to the functions.php file if possible? if/else to reset var to initial array if AJAX returns empty?
}
categoryIDs.forEach((item) => {
$.ajax({
type: \'POST\',
url: afp_vars.afp_ajax_url,
data: {
action: "load-filter",
category__in: categoryIDs
},
success: function (response) {
$(".filter-section").empty().html(response);
return false;
}
})
});
});
// AJAX Load More Posts scripts
// TODO: Fix this.
var canBeLoaded = true;
var bottomOffset = 1200;
var page = 2;
var loading = false;
var scrollHandling = {
allow: true,
reallow: function () {
scrollHandling.allow = true;
},
delay: 400
};
$(window).scroll(function () {
if (!loading && scrollHandling.allow) {
scrollHandling.allow = false;
setTimeout(scrollHandling.reallow, scrollHandling.delay);
if ($(document).scrollTop() > ($(document).height() - bottomOffset) && canBeLoaded == true) {
$.ajax({
type: \'POST\',
url: afp_vars.afp_ajax_url,
data: {
action: "afp_load_more",
page: page,
query: afp_vars.query
},
success: function (res) {
$(".filter-section").append(res);
page += 1;
}
})
}
}
});
最后,我的模板文件中有以下代码:
<!-- Filter Area -->
<div class="section">
<div class="container">
<h4 class="ctr">Choose a Filter Below</h4>
<div class="article-filters">
<form id="filter">
<?php
$args = array(
\'include\' => array(3, 4, 28, 35, 353),
\'orderby\' => \'name\',
\'order\' => \'ASC\',
\'posts_per_page\' => -1
);
$categories = get_categories($args);
foreach( $categories as $cat ) {
$cat_id = get_cat_ID( $cat->name );
echo \'<span>
<input class="checkbox-custom" type="checkbox" id="check\'. $cat_id .\'" name="category-checks" value="\' . $cat_id . \'">
<label class="checkbox-custom-label" for="check\'. $cat_id .\'">\' . $cat->name . \'</label>
</span>\';
}
wp_reset_postdata();
?>
</form>
</div>
<div class="filter-section">
<?php
$args = array(
\'post_type\' => \'post\',
\'post_status\' => \'publish\',
\'category__in\' => array(3, 4, 28, 35, 353),
\'posts_per_page\' => 9,
\'orderby\' => \'date\',
\'order\' => \'DESC\'
);
$filter_posts = new WP_Query($args);
if ( $filter_posts->have_posts() ) : while ( $filter_posts->have_posts() ) : $filter_posts->the_post();
?>
<article class="article-card">
<header class="card-header">
<div class="card-img" style="background: url(\'<?php echo the_post_thumbnail_url( \'small\' ); ?>\') no-repeat center center; width: 100%; background-size: cover;"></div>
<?php the_title( "<h4 class=\'article-title\'>", "</h4>" ) ?>
<p class="article-author">By <?php the_author(); ?></p>
</header>
<div class="card-content">
<p><?php echo wp_trim_words(get_post_meta(get_the_ID(), \'_yoast_wpseo_metadesc\', true), 15, \'...\'); ?></p>
</div>
<footer class="card-footer">
<a href="<?php the_permalink(); ?>" class="btn btn-article" role="button">Read Now</a>
</footer>
</article>
<?php $post_count = $filter_posts->current_post + 1; ?>
<?php if ($post_count % 3 == 0): ?>
<div class="ad-wrapper">
<?php the_ad(202070); ?>
</div>
<?php
endif;
endwhile; endif;
wp_reset_query();
?>
</div>
</div>
</div>
我使用了两个或三个不同的指南来将这一切修补在一起,所以我确信我在某个地方犯了一个错误。不幸的是,我不知道在哪里。我不希望有人帮我工作,但如果你能帮我找到问题,我将不胜感激!
最合适的回答,由SO网友:KreigD 整理而成
我这样解决问题:
在我的功能中。php文件中,我添加了以下代码:
if (empty($cat_id)) {
$cat_id = array(3, 4, 28, 35, 353);
}
在我的第二个AJAX函数中,如下所示:
function afp_load_more() {
$cat_id = $_POST[\'category__in\'];
if (empty($cat_id)) {
$cat_id = array(3, 4, 28, 35, 353);
}
...etc
所以当
categoryIDs
从我的JavaScript返回一个空数组(在用户单击任何复选框之前),它将默认为为复选框过滤器选择的五个类别。
在我的JavaScript中,我发现categoryIDs
变量在我的第二次AJAX调用中可用。我对该问题所做的唯一更改是添加category__in: categoryIDs
到数据数组下的第二个AJAX调用。
对于重复帖子的问题,我意识到我只需要设置一个灵长类计数器来增加posts_per_page
到offset
我的查询中的参数。
下面是我为滚动加载AJAX调用编写的已完成的JavaScript(注释中注明了更改):
// AJAX Load More Posts scripts
var canBeLoaded = true;
var bottomOffset = 1500;
var page = 2;
var postOffset = 9; // Added a variable for the offset
var loading = false;
var scrollHandling = {
allow: true,
reallow: function () {
scrollHandling.allow = true;
},
delay: 400
};
$(window).scroll(function () {
if (!loading && scrollHandling.allow) {
scrollHandling.allow = false;
setTimeout(scrollHandling.reallow, scrollHandling.delay);
if ($(document).scrollTop() > ($(document).height() - bottomOffset) && canBeLoaded == true) {
loading = true; // This is important but I forgot it last time around
$.ajax({
type: \'POST\',
url: afp_vars.afp_ajax_url,
data: {
action: "afp_load_more",
page: page,
query: afp_vars.query,
category__in: categoryIDs, // Added the variable from the first AJAX call here as-is because it\'s working now
offset: postOffset // Added the offset parameter with the variable to give it the value
},
success: function (res) {
$(".filter-section").append(res);
page += 1;
postOffset += 9; // Added a counter to add 9 to the offset on success because I load in 9 posts every time the AJAX call runs
loading = false; // This is important, but I forgot it last time around
}
})
}
}
});
哦,别忘了(像我一样)返回并使用AJAX调用到函数中的偏移量参数数据。php文件(在第二个AJAX函数中
$args
). 像这样:
$args[\'offset\'] = esc_attr( $_POST[\'offset\'] );
希望这对其他人有帮助。如果有人对我的代码提出批评,可以让它变得更好,
please 添加您的输入!