Membuat elemen

createElement, append, dan membangun UI dari data.

Daftar isi

Halaman yang isinya berganti terus tidak mungkin dibangun hanya dengan mengganti teks. Elemen baru perlu diciptakan dan disisipkan ke pohon DOM. Topik ini membahas createElement untuk membuat elemen kosong, append untuk menyisipkannya, dan pola paling umum yang menggabungkan keduanya, yaitu merender antarmuka dari array data. Pola inilah yang nantinya dipakai untuk menampilkan daftar hasil pencarian, item keranjang, atau baris tabel apa pun.

Membuat elemen baru dengan createElement#

Metode document.createElement() menerima satu nama tag dan mengembalikan elemen baru yang masih kosong. Elemen yang dihasilkan belum menjadi bagian halaman dan hanya hidup di memori sampai disisipkan dengan metode lain, sehingga bebas disiapkan lebih dahulu. Isinya diisi seperti elemen biasa, yaitu textContent untuk teks dan properti lain seperti className atau atribut bila diperlukan.

js Contoh: menyiapkan satu elemen li di memori
// tidak-dijalankan
const item = document.createElement("li");

item.textContent = "Menyapu lantai";
item.className = "tugas";

console.log(item.tagName); // LI, elemennya sudah ada tetapi belum tampil

Elemen yang dibuat mengikuti seluruh aturan elemen DOM lainnya, artinya event bisa dipasang, class bisa ditambahkan, dan isinya bisa diganti sebelum elemen itu tampil di halaman. Penyisipan atribut pun berjalan sama. setAttribute() menerima nama beserta nilainya, sedangkan properti seperti className cukup diisi langsung. Menyiapkan elemen di memori lebih dahulu juga menghindari halaman menampilkan potongan yang setengah jadi, karena penyisipan cukup dilakukan satu kali di akhir.

Satu kartu biasanya terdiri atas beberapa elemen yang disusun bertingkat, misalnya div pembungkus berisi h3 judul dan p keterangan. Polanya tetap sama, yaitu setiap bagian dibuat dengan createElement, diisi teksnya, lalu disusun dengan append dari dalam ke luar. Pembungkusnya disisipkan ke halaman pada langkah terakhir, sehingga seluruh kartu muncul sekaligus tanpa tahapan yang terlihat.

Menyisipkan elemen dengan append#

Metode append() milik elemen induk menaruh elemen baru di akhir daftar anaknya. Metode ini menerima satu atau beberapa argumen sekaligus, dan setiap argumennya boleh berupa node atau string teks. Bentuk lama appendChild() masih sering ditemui di kode lama, tetapi hanya menerima satu node dan tidak menerima string. Posisi sisipan yang lebih spesifik dapat dicapai lewat insertBefore() bila urutannya perlu dijaga di tengah daftar.

js Contoh: menyisipkan beberapa anak sekaligus
// tidak-dijalankan
const daftar = document.querySelector("#daftar");

daftar.append(
  buatItem("Menyapu lantai"),
  buatItem("Membersihkan papan tulis")
);

Urutan argumen menentukan urutan tampil. Argumen pertama mendarat paling atas dari yang disisipkan, tetapi tetap setelah anak-anak yang sudah ada sebelumnya. Selain menambah di akhir, DOM juga menyediakan prepend() untuk menyisipkan di awal dan remove() untuk melepas elemen dari halaman, ketiganya cukup untuk kebutuhan daftar yang sederhana.

Merender UI dari data#

Kombinasi keduanya membuka pola yang paling berguna, yaitu menyimpan konten sebagai array object lalu merender setiap item menjadi satu elemen. Fungsi perender menerima satu object, membuat elemennya, dan mengembalikannya, sedangkan pemanggil menampung hasilnya ke dalam elemen induk. Bila daftarnya panjang, DocumentFragment menampung elemen-elemen yang sudah jadi lebih dahulu, lalu seluruhnya disisipkan sekaligus sehingga browser hanya menggambar ulang satu kali.

js Contoh: fragment menampung banyak elemen sebelum disisipkan
// tidak-dijalankan
const fragmen = document.createDocumentFragment();

for (const tugas of daftarTugas) {
  fragmen.append(buatItem(tugas));
}

daftar.append(fragmen); // satu sisipan untuk seluruh isi fragmen

Pola perendernya juga mudah diperluas. Ketika perubahannya besar-besaran, seluruh daftar dapat dirender ulang dengan mengosongkan induknya lalu memanggil fungsi perender yang sama, dan tidak ada elemen yang perlu disunting satu per satu. Untuk perubahan kecil seperti menambah satu item, menyisipkan satu elemen saja sudah jauh lebih murah daripada merender ulang semuanya. Pemilihan di antara keduanya mengikuti besarnya perubahan pada data, bukan kebiasaan.

Demo berikut menerapkan pola ini pada jadwal piket kelas. Data tugas disimpan sebagai array object di dalam index.js, fungsi buatItem() mengubah satu object menjadi li, dan daftar dirender saat halaman dibuka. Tombol Tambah tugas mendorong satu object baru ke array, lalu menyisipkan satu li hasil buatItem() tanpa menyentuh item yang sudah tampil. Perhatikan bahwa array menjadi satu-satunya sumber kebenaran, sedangkan isi halaman selalu mengikutinya.

Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <title>Demo merender daftar dari array data</title>
  <style>
    body { font-family: "Segoe UI", Arial, sans-serif; margin: 14px; font-size: 14px; color: #1f2937; }
    #daftar { background: #f1f5f9; border: 1px solid #94a3b8; border-radius: 8px; padding: 10px 10px 10px 34px; max-width: 340px; }
    #daftar li { padding: 2px 6px; }
    #daftar li.tugas-baru { background: #dcfce7; }
    button { padding: 6px 12px; margin-top: 10px; margin-right: 8px; cursor: pointer; }
    #info { margin-top: 12px; padding: 10px; background: #eef2ff; border: 1px solid #4338ca; border-radius: 8px; min-height: 20px; max-width: 380px; }
  </style>
</head>
<body>
  <p>Jadwal piket kelas:</p>
  <ul id="daftar"></ul>
  <button id="tombol-tambah" type="button">Tambah tugas</button>
  <div id="info"></div>
  <script src="index.js"></script>

<script>
// Demo pembuatan elemen: merender UI dari array data.

const data = [
  { piket: "Ali", tugas: "Menyapu lantai" },
  { piket: "Budi", tugas: "Membersihkan papan tulis" },
  { piket: "Citra", tugas: "Menyiram tanaman" }
];

const daftar = document.querySelector("#daftar");
const info = document.querySelector("#info");

function buatItem(tugas) {
  const li = document.createElement("li");
  li.textContent = tugas.piket + ": " + tugas.tugas;
  return li;
}

function perbaruiInfo() {
  info.textContent = "Jumlah tugas pada array: " + data.length;
}

document.querySelector("#tombol-tambah").addEventListener("click", () => {
  const baru = { piket: "Dewi", tugas: "Merapikan meja" };
  data.push(baru);
  const item = buatItem(baru);
  item.className = "tugas-baru";
  daftar.append(item);
  perbaruiInfo();
});

for (const tugas of data) {
  daftar.append(buatItem(tugas));
}
perbaruiInfo();

</script>
<script>
// Demo pembuatan elemen: merender UI dari array data.

const data = [
  { piket: "Ali", tugas: "Menyapu lantai" },
  { piket: "Budi", tugas: "Membersihkan papan tulis" },
  { piket: "Citra", tugas: "Menyiram tanaman" }
];

const daftar = document.querySelector("#daftar");
const info = document.querySelector("#info");

function buatItem(tugas) {
  const li = document.createElement("li");
  li.textContent = tugas.piket + ": " + tugas.tugas;
  return li;
}

function perbaruiInfo() {
  info.textContent = "Jumlah tugas pada array: " + data.length;
}

document.querySelector("#tombol-tambah").addEventListener("click", () => {
  const baru = { piket: "Dewi", tugas: "Merapikan meja" };
  data.push(baru);
  const item = buatItem(baru);
  item.className = "tugas-baru";
  daftar.append(item);
  perbaruiInfo();
});

for (const tugas of data) {
  daftar.append(buatItem(tugas));
}
perbaruiInfo();

</script></body>
</html>

Kesalahan umum#

  1. Membuat elemen tanpa menyisipkannya. Elemen hasil createElement hanya hidup di memori dan tidak pernah tampil sampai append dipanggil. Gejalanya berupa daftar yang tetap kosong tanpa pesan error apa pun, dan penyebabnya hampir selalu sisipan yang terlupa.
  2. Menyisipkan node yang sama dua kali. append tidak menduplikasi node, tetapi memindahkan node yang sudah ada ke posisi baru. Elemen yang dikira tergandakan justru berpindah tempat. Bila dua salinan dibutuhkan, panggil createElement dua kali lewat fungsi yang sama.
  3. Merangkai string HTML di dalam perulangan. Baris daftar.innerHTML += item pada setiap putaran menulis ulang seluruh isi daftar. Elemen lama dibongkar lalu dibuat baru, dan listener yang terpasang di atasnya ikut hilang. Bangun elemennya dengan createElement, atau kumpulkan lebih dahulu di dalam fragment sebelum disisipkan.

Ringkasan#

  • document.createElement() membuat elemen kosong di memori yang baru tampil setelah disisipkan ke pohon DOM.
  • append() menaruh node atau string di akhir anak sebuah induk, menerima beberapa argumen sekaligus, dan berdampingan dengan prepend() serta remove().
  • Pola merender UI dari data mengubah setiap item array menjadi elemen lewat satu fungsi kecil, sehingga sumber data dan tampilan tetap terpisah.
  • DocumentFragment mengumpulkan banyak elemen sebelum disisipkan sekaligus, sehingga kerja penggambaran ulang browser diperpendek.

Referensi#