Cara Membuat Load More dengan jQuery Tanpa Plugin
Categories Tutorial Coding

Cara Membuat Load More dengan jQuery Tanpa Plugin

Kamu punya daftar berita, komentar, atau produk yang panjang, dan loading halaman terasa berat karena semuanya dirender sekaligus. Tombol Muat Lebih Banyak menyelesaikan masalah itu dengan cara yang sederhana. Panduan ini menunjukkan cara membuat load more dengan jQuery bertahap, dari permintaan data pertama sampai kondisi ketika data sudah habis.

Asumsinya kamu sudah punya endpoint yang menerima parameter halaman atau offset dan mengembalikan potongan data dalam format JSON. Kalau sumber datanya belum rapi, cara memuatnya bisa mengikuti pola di Cara Menampilkan Data API ke Tabel HTML dengan jQuery sebelum lanjut ke bagian berikut.

Struktur HTML dan Aturan State

Sebelum menulis JavaScript, tentukan dulu keadaan yang harus dilacak. Ada tiga variabel yang cukup untuk hampir semua kasus: nomor halaman saat ini, jumlah item per permintaan, dan penanda apakah masih ada data berikutnya.

<div id="daftar-postingan"></div>
<button id="tombol-muat" type="button">Muat Lebih Banyak</button>
<p id="pesan-kosong" hidden>Semua data sudah dimuat.</p>

Tiga elemen itu sudah cukup. Jangan taruh logika penanda di atribut seperti data-halaman di dalam tombol karena nilainya mudah tertinggal saat terjadi kesalahan di tengah proses. Simpan di variabel JavaScript yang jelas kepemilikannya.

var halaman = 1;
var perHalaman = 8;
var masihAda = true;
var sedangMemuat = false;

Variabel sedangMemuat mencegah permintaan kedua terkirim saat pengguna mengklik tombol berkali-kali. Ini masalah nyata: koneksi lambat membuat orang mengklik lagi, dan tanpa penjaga itu data yang sama bisa masuk dua kali.

Fungsi Memuat Data dengan $.ajax

Fungsi berikut mengambil satu halaman data, menyisipkannya ke daftar, lalu memperbarui state. Perhatikan bahwa penguncian tombol dilakukan di awal, bukan setelah respons datang.

function muatData() {
  if (sedangMemuat || !masihAda) return;

  sedangMemuat = true;
  $('#tombol-muat').prop('disabled', true).text('Memuat...');

  $.ajax({
    url: '/api/postingan',
    method: 'GET',
    data: { halaman: halaman, jumlah: perHalaman },
    dataType: 'json'
  })
  .done(function (hasil) {
    hasil.item.forEach(function (item) {
      $('#daftar-postingan').append(
        '<article class="kartu"><h3>' + item.judul + '</h3></article>'
      );
    });

    masihAda = hasil.item.length === perHalaman;
    halaman += 1;

    if (!masihAda) {
      $('#tombol-muat').hide();
      $('#pesan-kosong').prop('hidden', false);
    }
  })
  .fail(function () {
    $('#tombol-muat').text('Gagal, coba lagi');
  })
  .always(function () {
    sedangMemuat = false;
    if (masihAda) {
      $('#tombol-muat').prop('disabled', false).text('Muat Lebih Banyak');
    }
  });
}

Cara menentukan data sudah habis cukup dengan membandingkan panjang respons dengan perHalaman. Kalau server mengirim kurang dari jumlah yang diminta, berarti itu halaman terakhir. Server perlu mengembalikan nilai ini secara konsisten, karena kalau suatu saat mengirim 10 item padahal diminta 8, tombol akan terus muncul walaupun daftar sudah kering.

Memasang Klik dan Memuat Halaman Pertama

Tombol dihubungkan ke fungsi di atas, lalu halaman pertama dimuat otomatis saat dokumen siap. Kalau daftar awal sudah dirender server, panggilan pertama bisa dilewati dan halaman dimulai dari 2.

$(function () {
  $('#tombol-muat').on('click', muatData);
  muatData();
});

Perhatikan bahwa muatData dipanggil langsung sebagai referensi fungsi, bukan dibungkus function () { muatData(); }. Keduanya bekerja, tetapi bentuk pertama lebih pendek dan tidak membuat closure baru setiap kali.

Kalau Tombolnya Ditambahkan Belakangan

Beberapa tata letak menaruh tombol di luar kontainer yang dimuat ulang. Kalau tombol itu dibuat setelah halaman selesai dimuat, klik biasa tidak akan terbaca. Pasang listener di induk yang stabil dengan pola yang dijelaskan di Event Delegation jQuery untuk Elemen yang Ditambah Dinamis, lalu pindahkan handler ke sana.

Cara Menghindari Data Ganda dan Susunan Berubah

Ada dua jebakan yang sering muncul pada implementasi load more. Pertama, pengguna mengklik tombol dua kali sebelum respons pertama datang, sehingga halaman yang sama diminta dua kali. Kedua, data baru disisipkan di antara item lama sehingga urutan tampilan tidak lagi sesuai urutan asli.

  • Kunci tombol dengan prop('disabled', true) selama permintaan berjalan, bukan hanya mengganti teksnya.
  • Naikkan nomor halaman hanya di blok done, bukan sebelum permintaan dikirim.
  • Selalu append, jangan prepend, kecuali server memang mengirim data dari urutan terbaru ke terlama.
  • Kalau daftar bisa berubah di sisi server, kirim parameter urutan tetap seperti ID atau tanggal agar halaman tidak tumpang tindih.

Masalah halaman tumpang tindih biasanya bukan di sisi klien. Kalau server mengurutkan berdasarkan kolom yang nilainya bisa berubah, dua permintaan berurutan bisa mengembalikan item yang sama. Tambahkan kolom pengurut yang stabil di query, misalnya ID, sebagai kunci kedua.

Menambahkan Indikator dan Pesan Error

Tombol yang berubah teks menjadi “Memuat…” sudah cukup sebagai indikator untuk daftar pendek. Kalau datanya banyak dan prosesnya lambat, tambahkan elemen spinner terpisah di bawah daftar agar tinggi halaman tidak melompat saat teks tombol berubah.

<div id="spinner" hidden>Memuat...</div>

Tampilkan spinner di awal permintaan dengan $('#spinner').prop('hidden', false), lalu sembunyikan di blok always. Jangan lupa mengembalikan status tombol di blok yang sama supaya pengguna tetap bisa mencoba lagi ketika permintaan gagal karena jaringan.

Untuk pesan error, pisahkan antara kegagalan sementara dan data yang memang habis. Error jaringan sebaiknya tidak menghilangkan tombol, sedangkan data habis sebaiknya tidak menampilkan tombol sama sekali. Dua kondisi ini sering tertukar dan membuat pengguna mengklik tombol yang tidak akan pernah memuat apa pun.

Alternatif Ketika Tombol Tidak Diinginkan

Kalau desainnya tidak memakai tombol, pola yang sama bisa dipicu oleh IntersectionObserver ketika elemen penanda masuk ke viewport. Logika pengambilan data, penguncian, dan pengecekan akhir tetap sama, hanya pemicunya yang berbeda. Jangan menggabungkan keduanya dalam satu daftar karena keduanya bisa memicu permintaan bersamaan.

Untuk daftar yang isinya berubah karena input pengguna, misalnya hasil pencarian atau filter kategori, reset halaman ke 1 dan kosongkan wadah sebelum memuat ulang. Kalau langkah ini terlewat, hasil filter baru akan menempel di bawah hasil lama dan tampak seperti duplikasi.

Ringkasan

Load more dengan jQuery berdiri di atas tiga hal: state yang dilacak dengan benar, penguncian selama permintaan berjalan, dan pengecekan akhir yang konsisten dari server. Struktur kode di atas bisa dipindahkan ke komponen lain dengan sedikit penyesuaian, termasuk jika suatu saat kamu memuat data ke dalam tabel.

Pertanyaan yang Sering Diajukan

Apakah load more harus memakai plugin?

Tidak. Untuk satu tombol yang memuat satu halaman data, kode di atas lebih ringan dan lebih mudah dilacak daripada menambah dependensi. Plugin berguna kalau kamu butuh infinite scroll dengan pengaturan posisi yang rumit di banyak halaman sekaligus.

Bagaimana cara tahu data sudah habis?

Bandingkan jumlah item pada respons dengan jumlah yang diminta. Kalau kurang, itu halaman terakhir. Pastikan server selalu mengembalikan jumlah yang konsisten agar pengecekan ini tidak salah baca.

Kenapa data bisa muncul dua kali?

Biasanya karena nomor halaman dinaikkan sebelum permintaan selesai, atau tombol tidak dikunci saat proses berjalan. Pastikan kenaikan nomor halaman hanya terjadi di blok sukses dan tombol dinonaktifkan sejak permintaan dikirim.

Meja kerja developer dengan laptop berisi kode JavaScript dan diagram pohon DOM di buku catatan Prev Event Delegation jQuery untuk Elemen yang Ditambah Dinamis