Ajax加载异常求助:点击加载更多后重复加载整页内容
Root Cause
Your current setup retrieves the first job_count entries every time you click "Load More". Since you increment job_count by 10 each time, you're asking the server for the first 20, then 30 entries, etc. And using $('#latestJobs').load(...) replaces the entire tbody with these results—so you end up repeating all previous entries plus the new ones.
Solution: Implement Proper Pagination
We need to fetch only the new entries each time, not all previous ones. Here's how to adjust your code:
1. Update Frontend Code
We'll switch from replacing the tbody to appending new rows, and pass offset (starting position) instead of total count:
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script> $(document).ready(function() { var offset = 10; // We already show the first 10 entries, start next load at 11th $('#loadMoreJobs').click(function() { // Use $.post instead of load to append, not replace $.post('load_jobs.php', { offset: offset, limit: 10 }, function(response) { $('#latestJobs').append(response); offset += 10; // Hide button if no more jobs to load if (!response.trim()) { $('#loadMoreJobs').hide(); } }); }); }); </script> <tbody id="latestJobs"> <?php // Initial load: get first 10 jobs (offset 0, limit 10) $jobs = find_jobs_by_status('active', 10, 0); if (mysqli_num_rows($jobs) < 1) { echo '<tr class="job-listing-body">'; echo '<td colspan="6">No jobs found.</td>'; echo '</tr>'; } else { while ($job = mysqli_fetch_assoc($jobs)) { echo '<tr class="job-listing-body">'; echo '<td>' . $job['updated_at'] . '</td>'; echo '<td><a href="job_apply?job=' . $job['job_id'] . '">' . $job['title'] . '</a></td>'; echo '<td>0/' . $job['required_freelancers'] . '</td>'; echo '<td>' . $job['delivery_time'] . ' days</td>'; echo '<td>' . $job['budget'] . '</td>'; echo '<td><a href="job_apply?job=' . $job['job_id'] . '" class="btn btn-sm btn-apply-inv w-md waves-effect waves-light">Apply</a></td>'; echo '</tr>'; } } ?> </tbody> <button class="btn btn-secondary w-md waves-effect waves-light" id="loadMoreJobs">Load More</button>
2. Update Backend (load_jobs.php)
Modify it to accept offset and limit parameters, and return only the new entries:
<?php require_once('includes/initialize.php'); if (isset($_POST['offset']) && isset($_POST['limit'])) { $offset = (int)$_POST['offset']; $limit = (int)$_POST['limit']; $result = find_jobs_by_status('active', $limit, $offset); // Return empty if no more jobs, so frontend can hide the button if (mysqli_num_rows($result) < 1) { echo ''; } else { while ($job = mysqli_fetch_assoc($result)) { echo '<tr class="job-listing-body">'; echo '<td>' . $job['updated_at'] . '</td>'; echo '<td><a href="job_apply?job=' . $job['job_id'] . '">' . $job['title'] . '</a></td>'; echo '<td>0/' . $job['required_freelancers'] . '</td>'; echo '<td>' . $job['delivery_time'] . ' days</td>'; echo '<td>' . $job['budget'] . '</td>'; echo '<td><a href="job_apply?job=' . $job['job_id'] . '" class="btn btn-sm btn-apply-inv w-md waves-effect waves-light">Apply</a></td>'; echo '</tr>'; } mysqli_free_result($result); } } else { redirect_to('jobs'); } ?>
3. Update the find_jobs_by_status Function
You need to modify this function to support limit and offset for pagination (add these parameters to your query):
function find_jobs_by_status($status, $limit, $offset) { global $db; // Sanitize inputs to prevent SQL injection $status = mysqli_real_escape_string($db, $status); $limit = (int)$limit; $offset = (int)$offset; $sql = "SELECT * FROM jobs WHERE status = '{$status}' ORDER BY updated_at DESC LIMIT {$limit} OFFSET {$offset}"; $result = mysqli_query($db, $sql); confirm_query($result); // Make sure your confirm_query function handles errors return $result; }
Key Fixes Explained
- Append instead of Replace: Using
append()adds new rows to the existing tbody, instead of overwriting all content withload(). - Pagination Parameters:
offsettells the database where to start fetching new entries,limitdefines how many to get (10 in your case). - Hide Button When Done: If the server returns no new entries, we hide the "Load More" button to avoid unnecessary clicks.
- SQL Injection Protection: We sanitize inputs to keep your query safe.
内容的提问来源于stack exchange,提问作者yadiwap

