You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过XHR实现JSON分页数据无刷新渲染至HTML?

Got it, let's fix this pagination functionality step by step. First, let's clarify the core requirements: we need to fetch paginated JSON data via XHR, render both the content and pagination controls without page reloads, and handle prev/next buttons plus direct page jumps.

First, let's assume your sample JSON response looks like this (adjust if your structure is different):

{
  "data": [
    {"id": 1, "title": "Sample Item 1"},
    {"id": 2, "title": "Sample Item 2"}
  ],
  "pagination": {
    "current_page": 1,
    "total_pages": 5,
    "total_items": 10,
    "per_page": 2
  }
}

Here's the complete implementation, building on your existing code:

Step 1: Update HTML Structure (if needed)

Make sure you have containers for content and pagination controls:

<div id="content-container"></div>
<div class="pagination-controls">
  <button id="prev-btn">上一页</button>
  <span id="page-status">第 1 页 / 共 5 页</span>
  <button id="next-btn">下一页</button>
  <div class="page-jump">
    <input type="number" id="page-input" min="1" placeholder="输入页码">
    <button id="jump-btn">跳转</button>
  </div>
</div>

Step 2: Complete the JavaScript Logic

We'll add state tracking, data rendering, and event handlers:

// Track current pagination state
let currentPage = 1;
let totalPages = 1;

// DOM Elements
const contentContainer = document.getElementById('content-container');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const pageStatus = document.getElementById('page-status');
const pageInput = document.getElementById('page-input');
const jumpBtn = document.getElementById('jump-btn');

// Fetch data and render everything
function getData(page) {
  const xhr = new XMLHttpRequest();
  // Replace with your actual API endpoint
  xhr.open('GET', `/your-api-endpoint?page=${page}`, true);
  
  xhr.onload = function() {
    if (xhr.status === 200) {
      const response = JSON.parse(xhr.responseText);
      const { data, pagination } = response;
      
      // Update state
      currentPage = pagination.current_page;
      totalPages = pagination.total_pages;
      
      // Render content list
      renderContent(data);
      // Update pagination controls
      updatePaginationControls();
    } else {
      console.error('Failed to fetch data:', xhr.statusText);
      contentContainer.innerHTML = '<p>加载失败,请重试</p>';
    }
  };
  
  xhr.onerror = function() {
    console.error('Network error occurred');
    contentContainer.innerHTML = '<p>网络错误,请检查连接</p>';
  };
  
  xhr.send();
}

// Render the fetched data into the content container
function renderContent(data) {
  if (data.length === 0) {
    contentContainer.innerHTML = '<p>当前页没有数据</p>';
    return;
  }
  
  // Build HTML for items (adjust this to match your data structure)
  const itemsHtml = data.map(item => `
    <div class="list-item">
      <h3>${item.title}</h3>
      <p>ID: ${item.id}</p>
    </div>
  `).join('');
  
  contentContainer.innerHTML = itemsHtml;
}

// Update pagination buttons and status text
function updatePaginationControls() {
  // Update status text
  pageStatus.textContent = `第 ${currentPage} 页 / 共 ${totalPages} 页`;
  
  // Enable/disable prev button when on first page
  prevBtn.disabled = currentPage === 1;
  // Enable/disable next button when on last page
  nextBtn.disabled = currentPage === totalPages;
  
  // Update input's max attribute to prevent invalid entries
  pageInput.max = totalPages;
}

// Event handlers for pagination actions
prevBtn.addEventListener('click', () => {
  if (currentPage > 1) {
    getData(currentPage - 1);
  }
});

nextBtn.addEventListener('click', () => {
  if (currentPage < totalPages) {
    getData(currentPage + 1);
  }
});

jumpBtn.addEventListener('click', () => {
  const targetPage = parseInt(pageInput.value);
  // Validate input to avoid invalid requests
  if (isNaN(targetPage) || targetPage < 1 || targetPage > totalPages) {
    alert(`请输入1-${totalPages}之间的页码`);
    return;
  }
  if (targetPage !== currentPage) {
    getData(targetPage);
    // Clear input after successful jump
    pageInput.value = '';
  }
});

// Optional: Allow pressing Enter key to trigger page jump
pageInput.addEventListener('keypress', (e) => {
  if (e.key === 'Enter') {
    jumpBtn.click();
  }
});

// Initial load: fetch the first page on page load
getData(1);

Key Explanations:

  • State Tracking: We use currentPage and totalPages variables to keep track of the current pagination state, so we know exactly when to disable the prev/next buttons.
  • Separate Render Functions: Splitting getData, renderContent, and updatePaginationControls makes the code cleaner, easier to debug, and simpler to modify later.
  • Input Validation: We add checks to ensure users can't enter invalid page numbers, preventing unnecessary API requests and confusing error states.
  • Error Handling: Basic error handling for network issues and failed requests ensures users get clear feedback instead of a broken page.

Just adjust the API endpoint in getData to match your actual backend, and modify the renderContent function to fit your specific data fields (e.g., replace title and id with your JSON's actual properties).

内容的提问来源于stack exchange,提问作者Ulvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:18:10