简体   繁体   English

WordPress REST API Ajax 显示更多帖子按钮

[英]WordPress REST API Ajax show more posts button

PHP/HTML: PHP/HTML:

<ul id="load-more-div"></ul>
<a id="load-more" data-ppp="<?php echo get_option('posts_per_page'); ?>">load more</a>

JavaScripts: JavaScript:

(function($) {
  // Grab the load more button, since I only want to run the code if the button is on the page
  var loadMoreButton = $("#load-more");

  if (loadMoreButton) {
    // Get the posts_per_page number set in Reading Options
    var ppp = loadMoreButton.data("ppp");

    // Initialize function
    var loadPosts = function(page) {
      var theData, loadMoreContainer, errorStatus, errorMessage;

      // The AJAX request
      $.ajax({
        url: "/wp-json/wp/v2/posts",
        dataType: "json",
        data: {
          // Match the query that was already run on the page
          per_page: ppp,
          page: page,
          type: "post",
          orderby: "date"
        },
        success: function(data) {
          // Remove the button if the response returns no items
          if (data.length < 1) {
            loadMoreButton.remove();
          }

          // Create a place to store exactly what I need
          // Alternatively, the response can be filtered to only return the needed data, which is probably more efficient as the following loop wont be needed
          theData = [];

          // Get only what I need, and store it
          for (i = 0; i < data.length; i++) {
            theData[i] = {};
            theData[i].id = data[i].id;
            theData[i].link = data[i].link;
            theData[i].title = data[i].title.rendered;
            theData[i].content = data[i].content.rendered;
          }

          // Grab the container where my data will be inserted
          loadMoreContainer = $("#load-more-div");

          // For each object in my newly formed array, build a new element to store that data, and insert it into the DOM
          $.each(theData, function(i) {
            loadMoreContainer.append(
              '<li><a href="' +
                theData[i].link +
                '">' +
                theData[i].title +
                "</a></li>"
            );
          });
        },
        error: function(jqXHR, textStatus, errorThrown) {
          errorStatus = jqXHR.status + " " + jqXHR.statusText + "\n";
          errorMessage = jqXHR.responseJSON.message;

          // Show me what the error was
          console.log(errorStatus + errorMessage);
        }
      });
    };

    // Since our AJAX query is the same as the original query on the page (page 1), start with page 2
    var getPage = 2;

    // Actually implement the functionality when the button is clicked
    loadMoreButton.on("click", function() {
      loadPosts(getPage);
      // Increment the page, so on the next click we get the next page of results
      getPage++;
    });
  }
})(jQuery);

This is the trouble part, it doesn't remove the link.这是麻烦的部分,它不会删除链接。

// Remove the button if the response returns no items
if (data.length < 1) {
  loadMoreButton.remove();
}

Console errors when click the load more link after reaching the end of posts:到达帖子末尾后单击加载更多链接时出现控制台错误:

400 Bad Request 400 错误请求
The page number requested is larger than the number of pages available.请求的页码大于可用页数。

I found two ways to solve it:我找到了两种解决方法:

###Using data attribute ###使用数据属性

Get the max number of pages in the template, assign it to a data attribute, and access it in the scripts.获取模板中的最大页数,将其分配给数据属性,并在脚本中访问它。 Then check current page against total page numbers, and set disabled states to the load more button when it reaches the last page.然后根据总页码检查当前页面,并在到达最后一页时将加载更多按钮设置为禁用状态。

PHP/HTML: PHP/HTML:

<ul id="ajax-content"></ul>

<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>" data-pages="<?php echo $wp_query->max_num_pages; ?>">Show more</button>

JavaScripts: JavaScript:

(function($) {
    var loadMoreButton = $('#ajax-button');
    var loadMoreContainer = $('#ajax-content');
    if (loadMoreButton) {
        var endpoint = loadMoreButton.data('endpoint');
        var ppp = loadMoreButton.data('ppp');
        var pages = loadMoreButton.data('pages');
        var loadPosts = function(page) {
            var theData, errorStatus, errorMessage;
            $.ajax({
                url: endpoint,
                dataType: 'json',
                data: {
                    per_page: ppp,
                    page: page,
                    type: 'post',
                    orderby: 'date'
                },
                beforeSend: function() {
                    loadMoreButton.attr('disabled', true);
                },
                success: function(data) {
                    theData = [];
                    for (i = 0; i < data.length; i++) {
                        theData[i] = {};
                        theData[i].id = data[i].id;
                        theData[i].link = data[i].link;
                        theData[i].title = data[i].title.rendered;
                        theData[i].content = data[i].content.rendered;
                    }
                    $.each(theData, function(i) {
                        loadMoreContainer.append('<li><a href="' + theData[i].link + '">' + theData[i].title + '</a></li>');
                    });
                    loadMoreButton.attr('disabled', false);
                    if (getPage == pages) {
                        loadMoreButton.attr('disabled', true);
                    }
                    getPage++;
                },
                error: function(jqXHR) {
                    errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
                    errorMessage = jqXHR.responseJSON.message;
                    console.log(errorStatus + errorMessage);
                }
            });
        };
        var getPage = 2;
        loadMoreButton.on('click', function() {
            loadPosts(getPage);
        });
    }
})(jQuery);

###Using jQuery complete event ###Using jQuery complete事件

Get the total pages x-wp-totalpages from the HTTP response headers.从 HTTP 响应头中获取总页数x-wp-totalpages Then change the button states when reaches last page.然后在到达最后一页时更改按钮状态。

PHP/HTML: PHP/HTML:

<ul id="ajax-content"></ul>

<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>">Show more</button>

JavaScripts: JavaScript:

(function($) {
    var loadMoreButton = $('#ajax-button');
    var loadMoreContainer = $('#ajax-content');
    if (loadMoreButton) {
        var endpoint = loadMoreButton.data('endpoint');
        var ppp = loadMoreButton.data('ppp');
        var pager = 0;
        var loadPosts = function(page) {
            var theData, errorStatus, errorMessage;
            $.ajax({
                url: endpoint,
                dataType: 'json',
                data: {
                    per_page: ppp,
                    page: page,
                    type: 'post',
                    orderby: 'date'
                },
                beforeSend: function() {
                    loadMoreButton.attr('disabled', true);
                },
                success: function(data) {
                    theData = [];
                    for (i = 0; i < data.length; i++) {
                        theData[i] = {};
                        theData[i].id = data[i].id;
                        theData[i].link = data[i].link;
                        theData[i].title = data[i].title.rendered;
                        theData[i].content = data[i].content.rendered;
                    }
                    $.each(theData, function(i) {
                        loadMoreContainer.append('<li><a href="' + theData[i].link + '">' + theData[i].title + '</a></li>');
                    });
                    loadMoreButton.attr('disabled', false);
                },
                error: function(jqXHR) {
                    errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
                    errorMessage = jqXHR.responseJSON.message;
                    console.log(errorStatus + errorMessage);
                },
                complete: function(jqXHR) {
                    if (pager == 0) {
                        pager = jqXHR.getResponseHeader('x-wp-totalpages');
                    }
                    pager--;
                    if (pager == 1) {
                        loadMoreButton.attr('disabled', true);
                    }
                }
            });
        };
        var getPage = 2;
        loadMoreButton.on('click', function() {
            loadPosts(getPage);
            getPage++;
        });
    }
})(jQuery);

The problem appears to be an invalid query to that endpoint so the success: function() is never being run in this circumstance.问题似乎是对该端点的无效查询,因此在这种情况下永远不会运行success: function()


Add to All API Errors添加到所有 API 错误

You could add the same functionality for all errors like this...您可以为所有这样的错误添加相同的功能......

  error: function(jqXHR, textStatus, errorThrown) {
      loadMoreButton.remove();
      ....
  }

Though that may not be the desired way of handling of all errors.尽管这可能不是处理所有错误的理想方式。


Test for Existing Error Message测试现有错误消息

Another option could be to remove the button if you receive an error with that exact message...如果您收到带有该确切消息的错误,另一种选择可能是删除该按钮...

  error: function(jqXHR, textStatus, errorThrown) {
      if (jqXHR.statusText === 'The page number requested is larger than the number of pages available.') {
         loadMoreButton.remove();
      }
      ....
  }

but this would be susceptible to breaking with any changes to that error message.但这很容易因对该错误消息的任何更改而中断。


Return Custom Error Code from API从 API 返回自定义错误代码

The recommended way to handle it would be to return specific error code (along with HTTP status code 400) to specify the exact situation in a more reliable format...处理它的推荐方法是返回特定的错误代码(连同 HTTP 状态代码 400)以更可靠的格式指定确切的情况......

  error: function(jqXHR, textStatus, errorThrown) {
      if (jqXHR.statusCode === '215') {
         loadMoreButton.remove();
      }
      ....
  }

Here's an example on how to configure error handling in an API: Best Practices for API Error Handling以下是有关如何在 API 中配置错误处理的示例: API 错误处理的最佳实践


Return 200 HTTP Status Code返回 200 HTTP 状态码

The last option would be to change the way your API endpoint handles this type of "error"/situation, by returning a 200 level HTTP status code instead, which would invoke the success: instead of the error: callback instead.最后一个选项是更改 API 端点处理此类“错误”/情况的方式,方法是返回200级 HTTP 状态代码,这将调用success:而不是error:回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM