我试图在我的WordPress站点上使用AJAX作为用户滚动的帖子。我跟着this 但它对我的WordPress网站没有影响。
我使用了一个可以工作的插件,但我更愿意在没有插件的情况下学习如何做到这一点,既要学习,又要避免使用不必要的插件。下面的代码不起作用,尽管每页的帖子数设置为5,但我的所有帖子都会显示在页面上。
感谢您的帮助!
functions.php
function misha_my_load_more_scripts() {
global $wp_query;
wp_enqueue_script(\'jquery\');
wp_register_script( \'my_loadmore\', get_stylesheet_directory_uri() . \'/js/myloadmore.js\', array(\'jquery\') );
wp_localize_script( \'my_loadmore\', \'misha_loadmore_params\', array(
\'ajaxurl\' => site_url() . \'/wp-admin/admin-ajax.php\',
\'posts\' => json_encode( $wp_query->query_vars ),
\'current_page\' => get_query_var( \'paged\' ) ? get_query_var(\'paged\') : 1,
\'max_page\' => $wp_query->max_num_pages
) );
wp_enqueue_script( \'my_loadmore\' );
}
add_action( \'wp_enqueue_scripts\', \'misha_my_load_more_scripts\' );
function misha_loadmore_ajax_handler(){
$args = array(
\'cat\' => -21,
\'post_type\' => \'post\',
\'posts_per_page\' => 5,
\'paged\' => 1,
\'tax_query\' => array(
array(
\'taxonomy\' => \'topics\',
\'operator\' => \'NOT EXISTS\'
)
)
);
$args = json_decode( stripslashes( $_POST[\'query\'] ), true );
$args[\'paged\'] = $_POST[\'page\'] + 1; //need next page to be loaded
$args[\'post_status\'] = \'publish\';
$the_query = new WP_Query ( $args );
if($the_query->have_posts()) :
while($the_query->have_posts()) :
$the_query->the_post();
get_template_part( \'template-parts/post/content\', get_post_format() );
endwhile;
endif;
die;
}
add_action(\'wp_ajax_loadmore\', \'misha_loadmore_ajax_handler\'); // wp_ajax_{action}
add_action(\'wp_ajax_nopriv_loadmore\', \'misha_loadmore_ajax_handler\'); // wp_ajax_nopriv_{action}
myloadmore.js
jQuery(function($){
var canBeLoaded = true,
bottomOffset = 2000; //I\'ve played with this number to see if it was the offset calling posts too soon but it has no effect
$(window).scroll(function(){
var data = {
\'action\': \'loadmore\',
\'query\': misha_loadmore_params.posts,
\'page\' : misha_loadmore_params.current_page
};
if( $(document).scrollTop() > ( $(document).height() - bottomOffset ) && canBeLoaded == true ){
$.ajax({
url : misha_loadmore_params.ajaxurl,
data:data,
type:\'POST\',
beforeSend: function( xhr ){
canBeLoaded = false;
},
success:function(data){
if( data ) {
$(\'#main\').find(\'div:last-of-type\').after( data );
canBeLoaded = true;
misha_loadmore_params.current_page++;
}
}
});
}
});
});
一
<div class="row">
<div class="col-sm-6">
<?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), \'single-post-thumbnail\' ); ?>
<a href="<?php the_permalink(); ?>"><img src="<?php echo $image[0]; ?>" class="img-fluid"></a>
</div>
<div class="col-sm-6">
<?php
$categories = get_the_category();
if ( $categories ) :
$deepChild = get_deep_child_category( $categories );
?>
<p><?php echo $deepChild->name; ?></p>
<?php endif; ?>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
</div>
</div><!-- END ROW-->
front-page.php
<div id="main" class="container-fluid">
<?php misha_loadmore_ajax_handler(); ?>
</div><!-- END CONTAINER -->
UPDATED CODE 以下是基于答案的更新代码。我之所以发布这篇文章,是因为它仍然不起作用,我可能忽视了/误解了一些东西,我想知道我错在哪里了。
functions.php
function misha_my_load_more_scripts() {
wp_register_script( \'my_loadmore\', get_stylesheet_directory_uri() . \'/js/myloadmore.js\',
array( \'jquery\' ), \'\', true );
wp_enqueue_script( \'my_loadmore\' );
}
add_action( \'wp_enqueue_scripts\', \'misha_my_load_more_scripts\' );
function misha_loadmore_ajax_handler() {
$args = json_decode( wp_unslash( $_POST[\'query\'] ), true );
$args[\'paged\'] = $_POST[\'page\'] + 1; // load the next page
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( \'template-parts/content\', get_post_format() );
endwhile;
endif;
wp_die();
}
add_action( \'wp_ajax_loadmore\', \'misha_loadmore_ajax_handler\' ); // Authenticated users
add_action( \'wp_ajax_nopriv_loadmore\', \'misha_loadmore_ajax_handler\' ); // Non-authenticated users
myloadmore.js
jQuery(function($){
var canBeLoaded = true, // this param allows to initiate the AJAX call only if necessary
// the distance (in px) from the page bottom when you want to load more posts,
bottomOffset = ( $( \'#main > div.post:last\' ).offset() || {} ).top;
$(window).scroll(function(){
if ( misha_loadmore_params.current_page >= misha_loadmore_params.max_page ) {
// console.log( \'max_page reached; AJAX canceled\' );
return; // we\'ve already reached the last page, so let\'s do no more AJAX.
}
var data = {
\'action\': \'loadmore\',
\'query\': misha_loadmore_params.posts,
\'page\' : misha_loadmore_params.current_page
};
if( $(document).scrollTop() > ( $(document).height() - bottomOffset ) && canBeLoaded == true ){
$.ajax({
url : misha_loadmore_params.ajaxurl,
data: data,
type: \'POST\',
beforeSend: function( xhr ){
// you can also add your own preloader here
// you see, the AJAX call is in process, we shouldn\'t run it again until complete
canBeLoaded = false;
},
success:function(data){
if( data ) {
$(\'#main\').find(\'div.post:last-of-type\').after( data ); // where to insert posts
canBeLoaded = true; // the ajax is completed, now we can run it again
misha_loadmore_params.current_page++;
bottomOffset = ( $( \'#main > div.post:last\' ).offset() || {} ).top
}
}
});
}
});
});
一<div class="row">
<div class="col-sm-6">
<?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), \'single-post-thumbnail\' ); ?>
<a href="<?php the_permalink(); ?>"><img src="<?php echo $image[0]; ?>" class="img-fluid"></a>
</div>
<div class="col-sm-6">
<?php
$categories = get_the_category();
if ( $categories ) :
$deepChild = get_deep_child_category( $categories );
?>
<p><?php echo $deepChild->name; ?></p>
<?php endif; ?>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
</div>
</div><!-- END ROW-->
front-page.php
<?php
$current_page = max( 1, get_query_var( \'paged\' ) );
$the_query = new WP_Query( array(
\'cat\' => \'-21\',
\'post_type\' => \'post\',
\'posts_per_page\' => 5,
\'paged\' => $current_page,
) );
wp_localize_script( \'my_loadmore\', \'misha_loadmore_params\', array(
\'ajaxurl\' => admin_url( \'admin-ajax.php\', \'relative\' ),
\'posts\' => json_encode( $the_query->query_vars ),
\'current_page\' => $current_page,
\'max_page\' => $the_query->max_num_pages
) );
?>
<div id="main" class="container-fluid">
<?php
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
// Should match the one in misha_loadmore_ajax_handler().
get_template_part( \'template-parts/content\', get_post_format() );
endwhile;
endif;
?>
</div>
<?php wp_reset_postdata(); ?>
</div><!-- END CONTAINER -->
最合适的回答,由SO网友:Sally CJ 整理而成
工作代码基于我之前的答案,不使用nonce。。但是您可以检查前面关于如何实现nonce检查的答案并且代码基于您的代码。
misha_my_load_more_scripts()
在里面functions.php
function misha_my_load_more_scripts() {
wp_register_script( \'my_loadmore\', get_stylesheet_directory_uri() . \'/js/myloadmore.js\',
array( \'jquery\' ), \'\', true );
wp_enqueue_script( \'my_loadmore\' );
}
add_action( \'wp_enqueue_scripts\', \'misha_my_load_more_scripts\' );
misha_loadmore_ajax_handler()
在里面functions.php
function misha_loadmore_ajax_handler() {
$args = json_decode( wp_unslash( $_POST[\'query\'] ), true );
$args[\'paged\'] = $_POST[\'page\'] + 1; // load the next page
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( \'template-parts/post/content\', get_post_format() );
endwhile;
endif;
wp_die();
}
add_action( \'wp_ajax_loadmore\', \'misha_loadmore_ajax_handler\' ); // Authenticated users
add_action( \'wp_ajax_nopriv_loadmore\', \'misha_loadmore_ajax_handler\' ); // Non-authenticated users
front-page.php
(the#main
部门)
$current_page = max( 1, get_query_var( \'paged\' ) );
$the_query = new WP_Query( array(
\'cat\' => \'-21\',
\'post_type\' => \'post\',
\'posts_per_page\' => 5,
\'paged\' => $current_page,
) );
wp_localize_script( \'my_loadmore\', \'misha_loadmore_params\', array(
\'ajaxurl\' => admin_url( \'admin-ajax.php\', \'relative\' ),
\'posts\' => json_encode( $the_query->query_vars ),
\'current_page\' => $current_page,
\'max_page\' => $the_query->max_num_pages
) );
?>
<div id="main" class="container-fluid">
<?php
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
// Should match the one in misha_loadmore_ajax_handler().
get_template_part( \'template-parts/post/content\', get_post_format() );
endwhile;
endif;
?>
</div>
<?php
wp_reset_postdata();
myloadmore.js
和content.php
没有变化
实际上,在我的代码(我实际测试的代码)中更新,I don\'t have the tax_query
parameter, 但我在这个答案的前一个版本(不是本页的另一个版本)中错误地将其包含在上面的代码中。
因为tax_query
如下所示&mdash;未指定所需的terms
parameter &mdash;将导致0 = 1
在MySQL查询中,并最终导致没有结果(即没有帖子):
$the_query = new WP_Query( array(
...
\'tax_query\' => array(
array(
\'taxonomy\' => \'topics\',
\'operator\' => \'NOT EXISTS\',
// missing the required \'terms\' parameter
),
),
) );
所以一定要使用
tax_query
使用适当的参数。
您还可以使用/检查我的myloadmore.js
script?
SO网友:Sally CJ
您的代码有几个问题,例如:
原文code 依靠全球$wp_query
对象请参见global $wp_query;
在misha_my_load_more_scripts()
作用但您的代码使用的是自定义WP_Query
实例,即$the_query
在misha_loadmore_ajax_handler()
作用
在misha_loadmore_ajax_handler()
是AJAX处理程序/回调,因此不应从div#main
像这样:
<div id="main" class="container-fluid">
<?php misha_loadmore_ajax_handler(); ?>
</div><!-- END CONTAINER -->
因此原始代码可以工作;但是,对于自定义
WP_Query
请求,如
$the_query
在您的情况下,需要在
WP_Query
要求
你可以这样做:
首先,我使用的是the page, 我正在使用“滚动加载帖子(延迟加载)”脚本/选项。
其次,这是我的misha_my_load_more_scripts()
功能:
function misha_my_load_more_scripts() {
// register our main script but do not enqueue it yet
wp_register_script( \'my_loadmore\', \'URL/to/the/load-more-script\', array(\'jquery\') );
wp_enqueue_script( \'my_loadmore\' );
}
add_action( \'wp_enqueue_scripts\', \'misha_my_load_more_scripts\' );
和我的“main”
div
(邮政集装箱):
$current_page = max( 1, get_query_var( \'paged\' ) );
$the_query = new WP_Query([
\'posts_per_page\' => 5,
\'paged\' => $current_page,
]);
?>
<div id="main">
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
// This should match the one in misha_loadmore_ajax_handler().
get_template_part( \'template-parts/post/content\', get_post_format() );
endwhile; ?>
</div>
<script>
var misha_loadmore_params = {
ajaxurl: \'<?php echo admin_url( \'admin-ajax.php\', \'relative\' ); ?>\',
posts: \'<?php echo json_encode( $the_query->query_vars ); ?>\',
current_page: <?php echo $current_page; ?>,
max_page: <?php echo $the_query->max_num_pages; ?>
};
</script>
<?php
wp_reset_postdata();
这些是我所做的唯一改动
misha_loadmore_ajax_handler()
代码(
on that page) 可以按原样使用。
我已经尝试并测试了/我的代码,它正在按预期工作。虽然我没有使用您的代码,但我相信您可以使用您的代码/概念轻松实现我的代码。
如果要使用,请更新wp_localize_script()
(尤其是如果您希望在JS对象/数据中包含翻译后的文本,可能会更好),那么您需要将load more脚本排入页脚:
wp_register_script( \'my_loadmore\', \'URL/to/the/load-more-script\', array(\'jquery\'),
\'version\', true );
然后在“主要”
div
, 删除
<script>...</script>
并将此添加到
wp_reset_postdata()
:
wp_localize_script( \'my_loadmore\', \'misha_loadmore_params\', [
\'ajaxurl\' => admin_url( \'admin-ajax.php\', \'relative\' ),
\'posts\' => json_encode( $the_query->query_vars ),
\'current_page\' => $current_page,
\'max_page\' => $the_query->max_num_pages,
// These two are optional.
\'my_text\' => __( \'My text\', \'text-domain\' ),
\'security\' => wp_create_nonce( \'my-load-more-posts\' ),
] );
正如你所看到的,我在这里包括了一个翻译:
My text
(
misha_loadmore_params.my_text
).
Using a Nonce
在上面的本地化数据中,我还包含了一个nonce(
security
), 当您的AJAX PHP处理程序进行一些写操作时,这一点特别有用;e、 g.更新元数据。
您可以将其发送到PHP处理程序,如下所示:
// This is set in the load-more script.
var data = {
\'action\': \'loadmore\',
\'query\': misha_loadmore_params.posts,
\'page\' : misha_loadmore_params.current_page,
\'security\': misha_loadmore_params.security
};
然后在PHP处理程序中,您可以这样做来验证nonce:
function misha_loadmore_ajax_handler(){
check_ajax_referer( \'my-load-more-posts\', \'security\' );
...
wp_die();
}
PS:
This 我加载的脚本是否更多,与原始脚本相比只有一个区别,即
misha_loadmore_params.security
零件