Hari 15: JavaScript DOM Manipulation – Mengakses dan Mengubah Elemen HTML

Bagaimana JavaScript Bisa Mengubah Konten HTML Secara Dinamis? Hari Ini Kita Akan Membongkar Rahasia DOM Manipulation!

Keywords: JavaScript DOM, DOM manipulation, seleksi elemen, mengubah HTML, event listeners

Interaksi dengan pengguna adalah kunci website yang dinamis. Hari ini kita akan mempelajari DOM manipulation untuk berinteraksi dengan elemen HTML. Setelah mempelajari arrays dan objects, sekarang saatnya kita menerapkan pengetahuan tersebut untuk memanipulasi halaman web secara real-time!

Mengapa DOM Manipulation Penting dalam Web Development?

DOM (Document Object Model) adalah representasi struktur halaman web yang dapat dimanipulasi dengan JavaScript. Dengan DOM manipulation, Anda dapat:

  • Mengubah konten teks, HTML, dan atribut elemen
  • Mengubah gaya CSS elemen secara dinamis
  • Menambah atau menghapus elemen dari halaman
  • Merespons event pengguna seperti klik, hover, dan input
  • Membuat antarmuka pengguna yang interaktif dan responsif
  • Membangun aplikasi web single-page (SPA) tanpa reload

Menurut survei State of JS 2022, 92% developer JavaScript menggunakan DOM manipulation secara rutin dalam proyek mereka. Tanpa DOM manipulation, website akan statis dan tidak responsif terhadap interaksi pengguna.

Apa itu DOM?

DOM adalah antarmuka pemrograman untuk dokumen HTML. Ketika browser memuat halaman web, browser membuat DOM dari struktur HTML tersebut. DOM merepresentasikan dokumen sebagai struktur pohon di mana setiap node adalah objek yang mewakili bagian dari dokumen.

Contoh struktur HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Halaman Saya</title>
</head>
<body>
    <h1 id="judul">Selamat Datang</h1>
    <p class="paragraf">Ini adalah paragraf pertama.</p>
    <p class="paragraf">Ini adalah paragraf kedua.</p>
</body>
</html>

Struktur DOM yang dihasilkan:

Document
 └── html
     ├── head
        └── title
            └── "Halaman Saya"
     └── body
         ├── h1#judul
            └── "Selamat Datang"
         ├── p.paragraf
            └── "Ini adalah paragraf pertama."
         └── p.paragraf
             └── "Ini adalah paragraf kedua."

Mengakses Elemen DOM

JavaScript menyediakan beberapa metode untuk mengakses elemen DOM:

1. Mengakses Elemen Berdasarkan ID

Menggunakan getElementById() untuk mengakses elemen dengan ID unik:

// Mengakses elemen dengan ID "judul"
const judulElement = document.getElementById('judul');
console.log(judulElement); // <h1 id="judul">Selamat Datang</h1>

2. Mengakses Elemen Berdasarkan Class Name

Menggunakan getElementsByClassName() untuk mengakses elemen dengan class tertentu:

// Mengakses semua elemen dengan class "paragraf"
const paragrafElements = document.getElementsByClassName('paragraf');
console.log(paragrafElements); // HTMLCollection dengan 2 elemen <p>

// Mengakses elemen pertama
const firstParagraf = paragrafElements[0];
console.log(firstParagraf); // <p class="paragraf">Ini adalah paragraf pertama.</p>

3. Mengakses Elemen Berdasarkan Tag Name

Menggunakan getElementsByTagName() untuk mengakses elemen dengan tag tertentu:

// Mengakses semua elemen <p>
const pElements = document.getElementsByTagName('p');
console.log(pElements); // HTMLCollection dengan 2 elemen <p>

4. Mengakses Elemen dengan CSS Selector (Modern)

Menggunakan querySelector() dan querySelectorAll() untuk mengakses elemen dengan CSS selector:

// Mengakses elemen pertama dengan class "paragraf"
const firstParagraf = document.querySelector('.paragraf');
console.log(firstParagraf); // <p class="paragraf">Ini adalah paragraf pertama.</p>

// Mengakses semua elemen dengan class "paragraf"
const allParagraf = document.querySelectorAll('.paragraf');
console.log(allParagraf); // NodeList dengan 2 elemen <p>

// Mengakses elemen dengan ID "judul"
const judulElement = document.querySelector('#judul');
console.log(judulElement); // <h1 id="judul">Selamat Datang</h1>

// Mengakses elemen dengan kombinasi selector
const specificParagraf = document.querySelector('p.paragraf:nth-child(2)');
console.log(specificParagraf); // <p class="paragraf">Ini adalah paragraf kedua.</p>

5. Mengakses Elemen Relatif

Setelah mengakses satu elemen, Anda dapat mengakses elemen terkait:

const firstParagraf = document.querySelector('.paragraf');

// Mengakses parent element
const parentElement = firstParagraf.parentElement;
console.log(parentElement); // <body>...</body>

// Mengakses child elements
const childElements = parentElement.children;
console.log(childElements); // HTMLCollection dengan 3 elemen (h1, p, p)

// Mengakses next sibling
const nextSibling = firstParagraf.nextElementSibling;
console.log(nextSibling); // <p class="paragraf">Ini adalah paragraf kedua.</p>

// Mengakses previous sibling
const prevSibling = nextSibling.previousElementSibling;
console.log(prevSibling); // <p class="paragraf">Ini adalah paragraf pertama.</p>

Memanipulasi Konten Elemen

Setelah mengakses elemen, Anda dapat memanipulasi kontennya:

1. Mengubah Teks Konten

Menggunakan textContent untuk mengubah teks dalam elemen:

const judulElement = document.getElementById('judul');
judulElement.textContent = 'Judul Baru';
// Hasil: <h1 id="judul">Judul Baru</h1>

2. Mengubah HTML Konten

Menggunakan innerHTML untuk mengubah HTML dalam elemen:

const firstParagraf = document.querySelector('.paragraf');
firstParagraf.innerHTML = 'Ini adalah <strong>paragraf yang diperbarui</strong>.';
// Hasil: <p class="paragraf">Ini adalah <strong>paragraf yang diperbarui</strong>.</p>

Peringatan Keamanan: Menggunakan innerHTML dengan input pengguna dapat menyebabkan serangan XSS (Cross-Site Scripting). Gunakan textContent atau createElement untuk input pengguna.

3. Mendapatkan dan Mengatur Nilai Form

Menggunakan value untuk mendapatkan atau mengatur nilai form:

// Mengakses input field
const nameInput = document.querySelector('#name');

// Mendapatkan nilai
console.log(nameInput.value); // Nilai saat ini

// Mengatur nilai
nameInput.value = 'John Doe';

Memanipulasi Atribut Elemen

Anda dapat memanipulasi atribut elemen dengan beberapa metode:

1. Menggunakan getAttribute() dan setAttribute()

const linkElement = document.querySelector('a');

// Mendapatkan nilai atribut
const hrefValue = linkElement.getAttribute('href');
console.log(hrefValue); // "https://example.com"

// Mengatur nilai atribut
linkElement.setAttribute('href', 'https://new-example.com');
linkElement.setAttribute('target', '_blank');

2. Menggunakan Properti Langsung

Untuk atribut umum, Anda dapat menggunakan properti langsung:

const imgElement = document.querySelector('img');

// Mengatur src
imgElement.src = 'new-image.jpg';

// Mengatur alt
imgElement.alt = 'Deskripsi gambar baru';

// Mengatur class
imgElement.className = 'image-class';

3. Mengelola Class dengan classList

Menggunakan classList untuk menambah, menghapus, atau mengganti class:

const element = document.querySelector('.box');

// Menambah class
element.classList.add('active');
element.classList.add('highlight');

// Menghapus class
element.classList.remove('old-class');

// Mengganti class
element.classList.replace('old-class', 'new-class');

// Mengecek apakah elemen memiliki class tertentu
const hasActiveClass = element.classList.contains('active');
console.log(hasActiveClass); // true

// Toggle class (menambah jika tidak ada, menghapus jika ada)
element.classList.toggle('visible');

Memanipulasi Gaya CSS

Anda dapat mengubah gaya CSS elemen secara dinamis:

1. Menggunakan style Property

const element = document.querySelector('.box');

// Mengubah satu properti
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';
element.style.border = '1px solid #ccc';

// Mengubah beberapa properti sekaligus
Object.assign(element.style, {
    color: 'blue',
    fontSize: '16px',
    padding: '10px'
});

2. Menggunakan className atau classList

Lebih baik mengubah gaya dengan menambah atau menghapus class:

const element = document.querySelector('.box');

// Menambah class dengan gaya yang sudah didefinisikan di CSS
element.classList.add('highlight');

3. Menggunakan getComputedStyle()

Mendapatkan nilai gaya yang dihitung:

const element = document.querySelector('.box');
const computedStyle = getComputedStyle(element);

console.log(computedStyle.color); // Nilai warna yang dihitung
console.log(computedStyle.fontSize); // Nilai ukuran font yang dihitung

Membuat dan Menambah Elemen Baru

Anda dapat membuat elemen baru dan menambahkannya ke DOM:

1. Membuat Elemen Baru

// Membuat elemen <div>
const newDiv = document.createElement('div');

// Membuat elemen <p>
const newParagraph = document.createElement('p');

// Membuat elemen <a>
const newLink = document.createElement('a');

2. Menambah Konten ke Elemen Baru

const newParagraph = document.createElement('p');
newParagraph.textContent = 'Ini adalah paragraf baru.';
// Atau
newParagraph.innerHTML = 'Ini adalah <strong>paragraf baru</strong>.';

3. Menambah Atribut ke Elemen Baru

const newLink = document.createElement('a');
newLink.textContent = 'Kunjungi Situs';
newLink.setAttribute('href', 'https://example.com');
newLink.setAttribute('target', '_blank');

4. Menambah Elemen ke DOM

const container = document.querySelector('.container');
const newParagraph = document.createElement('p');
newParagraph.textContent = 'Paragraf baru.';

// Menambah sebagai child terakhir
container.appendChild(newParagraph);

// Menambah sebelum elemen tertentu
const referenceElement = document.querySelector('#reference');
container.insertBefore(newParagraph, referenceElement);

5. Mengganti Elemen

const oldElement = document.querySelector('.old');
const newElement = document.createElement('div');
newElement.textContent = 'Elemen baru.';

// Mengganti oldElement dengan newElement
oldElement.parentNode.replaceChild(newElement, oldElement);

6. Menghapus Elemen

const elementToRemove = document.querySelector('.remove-me');

// Menghapus dari parent
elementToRemove.parentNode.removeChild(elementToRemove);

// Cara modern (lebih sederhana)
elementToRemove.remove();

Contoh Implementasi: Aplikasi To-Do List Sederhana

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-Do List</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }

        .todo-container {
            background-color: #f9f9f9;
            border-radius: 5px;
            padding: 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }

        .todo-input {
            display: flex;
            margin-bottom: 20px;
        }

        .todo-input input {
            flex: 1;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-right: 10px;
        }

        .todo-input button {
            padding: 10px 15px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .todo-list {
            list-style: none;
            padding: 0;
        }

        .todo-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            border-bottom: 1px solid #eee;
        }

        .todo-item:last-child {
            border-bottom: none;
        }

        .todo-item.completed {
            text-decoration: line-through;
            color: #888;
        }

        .todo-item button {
            background-color: #f44336;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 5px 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="todo-container">
        <h1>To-Do List</h1>
        <div class="todo-input">
            <input type="text" id="todoInput" placeholder="Tambahkan tugas baru...">
            <button id="addButton">Tambah</button>
        </div>
        <ul class="todo-list" id="todoList">
            <!-- To-do items akan ditambahkan di sini -->
        </ul>
    </div>

    <script>
        // Mengakses elemen DOM
        const todoInput = document.getElementById('todoInput');
        const addButton = document.getElementById('addButton');
        const todoList = document.getElementById('todoList');

        // Fungsi untuk menambah to-do baru
        function addTodo() {
            const todoText = todoInput.value.trim();

            if (todoText === '') {
                alert('Masukkan tugas terlebih dahulu!');
                return;
            }

            // Membuat elemen <li> baru
            const todoItem = document.createElement('li');
            todoItem.className = 'todo-item';

            // Membuat elemen <span> untuk teks
            const todoTextElement = document.createElement('span');
            todoTextElement.textContent = todoText;

            // Membuat tombol hapus
            const deleteButton = document.createElement('button');
            deleteButton.textContent = 'Hapus';

            // Menambah event listener untuk tombol hapus
            deleteButton.addEventListener('click', function() {
                todoItem.remove();
            });

            // Menambah event listener untuk menandai selesai
            todoTextElement.addEventListener('click', function() {
                todoItem.classList.toggle('completed');
            });

            // Menyusun elemen
            todoItem.appendChild(todoTextElement);
            todoItem.appendChild(deleteButton);

            // Menambah ke list
            todoList.appendChild(todoItem);

            // Mengosongkan input
            todoInput.value = '';
            todoInput.focus();
        }

        // Menambah event listener untuk tombol tambah
        addButton.addEventListener('click', addTodo);

        // Menambah event listener untuk tombol Enter di input
        todoInput.addEventListener('keypress', function(event) {
            if (event.key === 'Enter') {
                addTodo();
            }
        });
    </script>
</body>
</html>

Praktik Terbaik dalam DOM Manipulation

  1. Minimalkan DOM Access – Akses DOM sesedikit mungkin karena operasi DOM mahal secara performa:
   // Buruk - mengakses DOM dalam loop
   for (let i = 0; i < 100; i++) {
       document.getElementById('counter').textContent = i;
   }

   // Baik - menggunakan variabel
   const counterElement = document.getElementById('counter');
   for (let i = 0; i < 100; i++) {
       counterElement.textContent = i;
   }
  1. Gunakan DocumentFragment untuk manipulasi massal:
   const fragment = document.createDocumentFragment();

   for (let i = 0; i < 100; i++) {
       const li = document.createElement('li');
       li.textContent = `Item ${i}`;
       fragment.appendChild(li);
   }

   document.getElementById('list').appendChild(fragment);
  1. Debounce Event Handlers untuk event yang sering terjadi:
   function debounce(func, wait) {
       let timeout;
       return function() {
           const context = this;
           const args = arguments;
           clearTimeout(timeout);
           timeout = setTimeout(() => func.apply(context, args), wait);
       };
   }

   // Menggunakan debounce untuk event resize
   window.addEventListener('resize', debounce(() => {
       console.log('Resize event');
   }, 300));
  1. Gunakan Event Delegation untuk elemen yang dinamis:
   // Buruk - menambah event listener untuk setiap item
   document.querySelectorAll('.item').forEach(item => {
       item.addEventListener('click', function() {
           console.log('Item clicked');
       });
   });

   // Baik - menggunakan event delegation
   document.getElementById('container').addEventListener('click', function(event) {
       if (event.target.classList.contains('item')) {
           console.log('Item clicked');
       }
   });
  1. Hindari Inline Event Handlers – Gunakan addEventListener alih-alih atribut HTML:
   // Buruk
   <button onclick="doSomething()">Klik</button>

   // Baik
   <button id="myButton">Klik</button>
   <script>
       document.getElementById('myButton').addEventListener('click', doSomething);
   </script>

Debugging DOM Manipulation

Saat mengalami masalah dengan DOM manipulation:

  1. Gunakan console.log() untuk memeriksa elemen:
   const element = document.querySelector('.my-element');
   console.log(element); // Periksa apakah elemen ditemukan
  1. Gunakan browser debugger untuk menelusuri eksekusi kode baris per baris
  2. Periksa apakah DOM sudah dimuat – Pastikan kode berjalan setelah DOM siap:
   // Cara 1: Menempatkan script sebelum penutup body
   <script>
       // Kode Anda di sini
   </script>
   </body>

   // Cara 2: Menggunakan DOMContentLoaded event
   document.addEventListener('DOMContentLoaded', function() {
       // Kode Anda di sini
   });
  1. Gunakan browser developer tools untuk memeriksa struktur DOM dan perubahan yang terjadi

Kesimpulan

DOM manipulation adalah kemampuan fundamental yang memungkinkan JavaScript berinteraksi dengan halaman web. Hari ini Anda telah mempelajari:

  • Cara mengakses elemen DOM dengan berbagai metode
  • Cara memanipulasi konten, atribut, dan gaya elemen
  • Cara membuat, menambah, dan menghapus elemen baru
  • Implementasi nyata dengan contoh aplikasi to-do list
  • Praktik terbaik dalam DOM manipulation

Dengan menguasai DOM manipulation, Anda telah membuka kemampuan untuk membuat website yang interaktif dan responsif. Konsep ini adalah fondasi untuk topik lebih lanjut seperti event handling, form validation, dan bahkan framework JavaScript modern.

Teruslah berlatih dengan membuat berbagai interaksi DOM untuk memperkuat pemahaman Anda. Semakin sering Anda berlatih, semakin alami konsep ini akan terasa dalam pembuatan website sehari-hari Anda.

Buat halaman HTML dengan tombol yang mengubah konten saat diklik menggunakan JavaScript, lalu share hasilnya! Kami akan memberikan feedback dan tips untuk meningkatkan keterampilan coding Anda. Paling kreatif akan kita highlight di postingan minggu depan dan dapatkan kesempatan untuk ditampilkan di galeri proyek kami! Jangan lupa gunakan hashtag #30HariWebDevChallenge!

#JavaScript #DOM #WebInteractivity #JSIndonesia

Leave a Comment