如何不使用jQuery AJAX,用纯JS实现文章加载?
纯JS实现WordPress文章加载的疑问解答
提问内容
我想不使用jQuery AJAX,用纯JS实现文章加载功能。在网上找到相关教程后有两个疑问:
- fetch方法里的请求路径该怎么设置?(示例里用的是
fetch(/wp-json/blog-posts/all-posts)); get_custom_post_types_api()函数里的/all-posts是什么意思?如果我的博客地址是http://site-name.net/blog/,这个路径该怎么配置?
问题1:fetch请求路径的设置
fetch里的路径是WordPress REST API的自定义路由地址,核心格式是/wp-json/命名空间/路由后缀。
- 原示例路径存在错误:原PHP代码注册的命名空间是
post(原代码少了引号,属于语法错误),所以正确的基础路径应该是/wp-json/post/all-posts; - 针对你的博客地址
http://site-name.net/blog/(WordPress安装在/blog/子目录),路径要改成/blog/wp-json/post/all-posts——因为wp-json是WordPress REST API的固定入口,必须放在你的WordPress安装目录后面。
问题2:/all-posts的含义与路径配置
/all-posts是你自定义的REST API路由后缀,用来标识这个接口的功能(这里是获取所有文章),你可以改成任意名字(比如/get-posts),只要前后端的路径对应上就行;- 针对你的子目录博客,配置方式分两种:
- 沿用原命名空间:保持PHP里的
register_rest_route('post', '/all-posts', ...),对应的fetch路径就是/blog/wp-json/post/all-posts; - 自定义命名空间(推荐,避免和默认API冲突):把PHP里的注册代码改成
register_rest_route('blog/v1', '/all-posts', ...),对应的fetch路径就是/blog/wp-json/blog/v1/all-posts。
- 沿用原命名空间:保持PHP里的
修正后的完整代码
纯JS加载逻辑
function chunkArray(array, size) { const chunkyArr = []; let index = 0; while (index < array.length) { chunkyArr.push(array.slice(index, size + index)); index += size; } return chunkyArr; } function loadButton(modifier) { if (modifier === "hide" && button) button.style.display = "none"; if (modifier === "show" && button) button.style.display = "block"; } const itemsContainer = document.querySelector(".cb-articles-grid__items"); const postsShown = 4; let count = 0; const button = document.querySelector(".load-more"); button.addEventListener("click", () => { // 适配/blog/子目录的路径 fetch(`/blog/wp-json/post/all-posts`) .then((response) => response.json()) .then((data) => { // 修正原代码的Util.chunkArray,直接用已定义的chunkArray函数 const newData = chunkArray(data, postsShown); const currentChunk = newData[count]; if (count < newData.length) { const items = []; // 简化forEach循环,直接遍历post对象 currentChunk.forEach((post) => { const article = `<article class="c-article-item fadeIn"> <a class="c-article-item__link" href="${post.url}"> <div class="c-article-item__image"> <img src="${post.featured_img_src}" alt="${post.title}"> </div> <p class="c-article-item__date">${post.date}</p> <div class="c-article-item__text"> <h3 class="c-article-item__title">${post.title}</h3> <p class="c-article-item__excerpt">${post.excerpt}</p> </div> </a></article>`; items.push(article); }); itemsContainer.insertAdjacentHTML("beforeend", items.join("")); count++; if (count === newData.length) loadButton("hide"); } else { loadButton("hide"); } }) .catch((err) => { console.log("加载失败!", err); }); });
WordPress functions.php代码
function get_blog_post_type($request) { $posts_data = array(); $paged = $request->get_param('page'); $paged = (isset($paged) && !empty($paged)) ? $paged : 1; $blogPosts = get_posts( array( 'post_type' => 'post', 'status' => 'published', 'posts_per_page' => -1, 'orderby' => 'post_date', 'order' => 'DESC', 'paged' => $paged ) ); foreach ($blogPosts as $post) { $id = $post->ID; $post_thumbnail = (has_post_thumbnail($id)) ? get_the_post_thumbnail_url($id) : null; // 补充原代码缺失的date字段,确保JS能拿到日期数据 $posts_data[] = (object)array( 'id' => $id, 'slug' => $post->post_name, 'type' => $post->post_type, 'title' => $post->post_title, 'featured_img_src' => $post_thumbnail, 'url' => get_permalink($id), 'excerpt' => mb_strimwidth(get_the_excerpt($id), 0, 180, '...'), 'date' => get_the_date('Y-m-d', $id) ); } return $posts_data; } add_action('rest_api_init', 'get_custom_post_types_api'); function get_custom_post_types_api() { // 修正原代码的语法错误:第一个参数添加引号 register_rest_route('post', '/all-posts', array( 'methods' => 'GET', 'callback' => 'get_blog_post_type' )); // 若要使用自定义命名空间,替换为下面的代码: // register_rest_route('blog/v1', '/all-posts', array( // 'methods' => 'GET', // 'callback' => 'get_blog_post_type' // )); }
加载按钮HTML
<button class="load-more">加载更多文章</button>
内容的提问来源于stack exchange,提问作者natal
相关产品推荐
相关产品推荐

