Bab 4: DOM Manipulation
Bab 4: DOM Manipulation
4.1 Pengenalan Document Object Model (DOM)
4.1.1 Apa itu DOM?
Struktur representasi dokumen HTML/XML
Tree structure dari dokumen
Node types dan hierarki
Window object vs Document object
DOM Level dan standards
4.1.2 DOM Tree Structure
// Contoh struktur DOM
/*
document
├── html
│ ├── head
│ │ ├── title
│ │ └── meta
│ └── body
│ ├── div
│ ├── p
│ └── script
*/
// Mengakses struktur DOM
console.log(document.documentElement); // html element
console.log(document.head); // head element
console.log(document.body); // body element
4.2 Seleksi Element
4.2.1 Basic Selectors
// By ID
const elementById = document.getElementById('myId');
// By Class Name
const elementsByClass = document.getElementsByClassName('myClass');
// By Tag Name
const elementsByTag = document.getElementsByTagName('div');
// Query Selector
const element = document.querySelector('.myClass');
const elements = document.querySelectorAll('.myClass');
// Query Selector dengan Complex Selectors
const complexElement = document.querySelector('div.myClass > p:first-child');
4.2.2 Advanced Selection Methods
// Closest parent matching selector
const closestParent = element.closest('.container');
// Direct children
const children = element.children;
// First and last child
const firstChild = element.firstElementChild;
const lastChild = element.lastElementChild;
// Siblings
const nextSibling = element.nextElementSibling;
const previousSibling = element.previousElementSibling;
// Parent
const parent = element.parentElement;
4.3 Modifikasi Element
4.3.1 Content Modification
// Text content
element.textContent = 'New text';
// Inner HTML
element.innerHTML = '<span>New HTML</span>';
// Outer HTML
element.outerHTML = '<div>Replace entire element</div>';
// Value (untuk form elements)
inputElement.value = 'New value';
4.3.2 Attributes Manipulation
// Get attribute
const value = element.getAttribute('data-id');
// Set attribute
element.setAttribute('data-id', '123');
// Remove attribute
element.removeAttribute('data-id');
// Check attribute existence
const hasAttribute = element.hasAttribute('data-id');
// Data attributes
element.dataset.customData = 'value';
console.log(element.dataset.customData);
4.3.3 Style Manipulation
// Direct style
element.style.backgroundColor = 'red';
element.style.fontSize = '16px';
// Classes
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('visible');
element.classList.replace('old', 'new');
element.classList.contains('active');
// Multiple classes
element.className = 'class1 class2 class3';
4.4 Creating dan Removing Elements
4.4.1 Creating Elements
// Create new element
const newDiv = document.createElement('div');
// Create text node
const textNode = document.createTextNode('Hello World');
// Create element with content
const paragraph = document.createElement('p');
paragraph.textContent = 'New paragraph';
// Create complex structure
const container = document.createElement('div');
container.innerHTML = `
<h2>Title</h2>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
`;
4.4.2 Adding Elements to DOM
// Append at end
parent.appendChild(newElement);
// Insert before specific element
parent.insertBefore(newElement, referenceElement);
// Insert at specific position
parent.insertAdjacentElement('beforebegin', element);
parent.insertAdjacentElement('afterbegin', element);
parent.insertAdjacentElement('beforeend', element);
parent.insertAdjacentElement('afterend', element);
// Insert HTML
element.insertAdjacentHTML('beforeend', '<div>New content</div>');
4.4.3 Removing Elements
// Remove element
element.remove();
// Remove child
parent.removeChild(child);
// Clear all children
while (element.firstChild) {
element.removeChild(element.firstChild);
}
4.5 Event Handling
4.5.1 Basic Event Handling
// Adding event listener
element.addEventListener('click', function(event) {
console.log('Clicked!');
});
// Removing event listener
const handler = function(event) {
console.log('Handled!');
};
element.addEventListener('click', handler);
element.removeEventListener('click', handler);
// Inline event handling (not recommended)
element.onclick = function() {
console.log('Clicked!');
};
4.5.2 Event Object Properties
element.addEventListener('click', function(event) {
// Event properties
console.log(event.type); // Type of event
console.log(event.target); // Element that triggered event
console.log(event.currentTarget); // Element handling event
console.log(event.clientX); // Mouse X coordinate
console.log(event.clientY); // Mouse Y coordinate
// Prevent default behavior
event.preventDefault();
// Stop propagation
event.stopPropagation();
});
4.5.3 Event Types
// Mouse events
element.addEventListener('click', handler);
element.addEventListener('dblclick', handler);
element.addEventListener('mousedown', handler);
element.addEventListener('mouseup', handler);
element.addEventListener('mouseover', handler);
element.addEventListener('mouseout', handler);
element.addEventListener('mousemove', handler);
// Keyboard events
element.addEventListener('keydown', handler);
element.addEventListener('keyup', handler);
element.addEventListener('keypress', handler);
// Form events
element.addEventListener('submit', handler);
element.addEventListener('change', handler);
element.addEventListener('input', handler);
element.addEventListener('focus', handler);
element.addEventListener('blur', handler);
// Document/Window events
window.addEventListener('load', handler);
window.addEventListener('DOMContentLoaded', handler);
window.addEventListener('resize', handler);
window.addEventListener('scroll', handler);
4.6 Event Bubbling dan Capturing
4.6.1 Event Flow
// Bubbling phase (default)
parent.addEventListener('click', function(event) {
console.log('Parent clicked - bubbling');
});
// Capturing phase
parent.addEventListener('click', function(event) {
console.log('Parent clicked - capturing');
}, true);
// Stop bubbling
child.addEventListener('click', function(event) {
event.stopPropagation();
console.log('Child clicked - event stopped');
});
4.7 DOM Traversal
4.7.1 Node Navigation
// Node relationships
const parent = node.parentNode;
const children = node.childNodes;
const siblings = node.siblings;
// Element navigation
const firstChild = element.firstElementChild;
const lastChild = element.lastElementChild;
const parent = element.parentElement;
const nextSibling = element.nextElementSibling;
const previousSibling = element.previousElementSibling;
4.8 Praktik dan Latihan
4.8.1 Project: Dynamic Form Generator
class FormGenerator {
constructor(container) {
this.container = container;
}
addField(type, label, options = {}) {
const field = document.createElement('div');
// Implementation
}
generateForm() {
// Implementation
}
}
4.8.2 Project: Interactive Todo List
class TodoList {
constructor(container) {
this.container = container;
this.tasks = [];
this.setupEventListeners();
}
addTask(text) {
// Implementation
}
removeTask(id) {
// Implementation
}
toggleTask(id) {
// Implementation
}
}
4.9 Performance Optimization
Minimizing DOM access
Document fragments
Event delegation
Reflow dan repaint considerations
Memory leak prevention
4.10 Best Practices
Caching DOM queries
Using appropriate selectors
Event delegation for dynamic elements
Clean up event listeners
Error handling
4.11 Ringkasan
DOM fundamentals
Selection dan manipulation methods
Event handling
Common patterns dan solutions
4.12 Latihan Akhir Bab
Create a dynamic navigation menu
Build an image slider
Implement a form validator
Create a drag and drop interface
Build an interactive modal system
coding full
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM Manipulation Examples</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
body {
padding: 20px;
background-color: #f0f0f0;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 4px;
}
h2 {
margin-bottom: 15px;
color: #333;
}
button {
padding: 8px 16px;
margin: 5px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.demo-element {
padding: 10px;
margin: 10px 0;
background-color: #f8f9fa;
border: 1px solid #ddd;
}
.highlight {
background-color: yellow;
}
.error {
color: red;
}
.success {
color: green;
}
#elementCreationDemo {
min-height: 100px;
border: 1px dashed #ccc;
padding: 10px;
margin-top: 10px;
}
.event-demo {
padding: 20px;
background-color: #e9ecef;
text-align: center;
margin: 10px 0;
cursor: pointer;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="container">
<h1>DOM Manipulation Examples</h1>
<!-- Element Selection Demo -->
<section id="selectionDemo">
<h2>Element Selection</h2>
<div id="myId" class="demo-element">Element with ID</div>
<div class="myClass demo-element">Element with Class 1</div>
<div class="myClass demo-element">Element with Class 2</div>
<button onclick="demonstrateSelectors()">Demonstrate Selectors</button>
</section>
<!-- Element Modification Demo -->
<section id="modificationDemo">
<h2>Element Modification</h2>
<div id="modifyContent" class="demo-element">Original Content</div>
<button onclick="modifyText()">Modify Text</button>
<button onclick="modifyHTML()">Modify HTML</button>
<button onclick="modifyAttributes()">Modify Attributes</button>
<button onclick="modifyStyles()">Modify Styles</button>
</section>
<!-- Element Creation Demo -->
<section>
<h2>Element Creation</h2>
<button onclick="createElements()">Create Elements</button>
<div id="elementCreationDemo"></div>
</section>
<!-- Event Handling Demo -->
<section id="eventDemo">
<h2>Event Handling</h2>
<div class="event-demo" id="eventArea">
Click me! Then try hovering and other events.
</div>
<div id="eventLog"></div>
</section>
<!-- Form Validation Demo -->
<section>
<h2>Form Validation</h2>
<form id="validationForm" novalidate>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" required>
</div>
<button type="submit">Submit</button>
</form>
</section>
</div>
<script>
// Element Selection Demo
function demonstrateSelectors() {
// By ID
const elementById = document.getElementById('myId');
elementById.classList.toggle('highlight');
// By Class Name
const elementsByClass = document.getElementsByClassName('myClass');
Array.from(elementsByClass).forEach(el => {
el.classList.toggle('highlight');
});
// Query Selector
const element = document.querySelector('.myClass');
element.style.fontWeight = element.style.fontWeight === 'bold' ? 'normal' : 'bold';
}
// Element Modification Demo
function modifyText() {
const element = document.getElementById('modifyContent');
element.textContent = 'Text Modified at: ' + new Date().toLocaleTimeString();
}
function modifyHTML() {
const element = document.getElementById('modifyContent');
element.innerHTML = '<strong>HTML Modified</strong> with <em>formatting</em>';
}
function modifyAttributes() {
const element = document.getElementById('modifyContent');
element.setAttribute('data-modified', 'true');
element.dataset.timestamp = Date.now();
alert('Attributes added! Check element inspector.');
}
function modifyStyles() {
const element = document.getElementById('modifyContent');
element.style.backgroundColor = '#' + Math.floor(Math.random()*16777215).toString(16);
element.style.padding = '20px';
element.style.borderRadius = '8px';
element.style.transition = 'all 0.3s ease';
}
// Element Creation Demo
function createElements() {
const container = document.getElementById('elementCreationDemo');
container.innerHTML = ''; // Clear previous content
// Create new element
const div = document.createElement('div');
div.className = 'demo-element';
div.textContent = 'Dynamically created element';
// Create text node
const text = document.createTextNode(' - Created at: ' + new Date().toLocaleTimeString());
div.appendChild(text);
// Add to DOM
container.appendChild(div);
}
// Event Handling Demo
const eventArea = document.getElementById('eventArea');
const eventLog = document.getElementById('eventLog');
function logEvent(eventType) {
const log = document.createElement('div');
log.textContent = `${eventType} at ${new Date().toLocaleTimeString()}`;
eventLog.prepend(log);
if (eventLog.children.length > 5) {
eventLog.removeChild(eventLog.lastChild);
}
}
eventArea.addEventListener('click', (e) => {
logEvent('Click');
e.target.style.backgroundColor = '#' + Math.floor(Math.random()*16777215).toString(16);
});
eventArea.addEventListener('mouseover', () => logEvent('Mouse Over'));
eventArea.addEventListener('mouseout', () => logEvent('Mouse Out'));
// Form Validation Demo
const form = document.getElementById('validationForm');
form.addEventListener('submit', (e) => {
e.preventDefault();
const username = document.getElementById('username');
const email = document.getElementById('email');
let isValid = true;
// Username validation
if (!username.value.trim()) {
showError(username, 'Username is required');
isValid = false;
} else {
showSuccess(username);
}
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!email.value.trim()) {
showError(email, 'Email is required');
isValid = false;
} else if (!emailRegex.test(email.value.trim())) {
showError(email, 'Please enter a valid email');
isValid = false;
} else {
showSuccess(email);
}
if (isValid) {
alert('Form submitted successfully!');
form.reset();
}
});
function showError(input, message) {
const formGroup = input.parentElement;
formGroup.querySelector('.error-message')?.remove();
const error = document.createElement('div');
error.className = 'error-message error';
error.textContent = message;
formGroup.appendChild(error);
input.style.borderColor = 'red';
}
function showSuccess(input) {
const formGroup = input.parentElement;
formGroup.querySelector('.error-message')?.remove();
input.style.borderColor = 'green';
}
</script>
</body>
</html>
Last updated