DOM Manipulation - Exercise 2

The document.createElement() method creates a new HTML element in memory. You pass the tag name as a string, and it returns a new element node that you can then add to the page.

javascript

// Create a new paragraph element
const newParagraph = document.createElement('p');

// Create a new div element
const newDiv = document.createElement('div');

// Create a new button element
const newButton = document.createElement('button');

// Set content and attributes
newParagraph.textContent = 'This is a new paragraph.';
newDiv.id = 'myDiv';
newButton.textContent = 'Click Me';

console.log(newParagraph); // <p>This is a new paragraph.</p>

The appendChild() method adds a node as the last child of a parent element. It returns the appended child node. If the child already exists in the DOM, it will be moved to the new position.

javascript

// Create a new list item
const newItem = document.createElement('li');
newItem.textContent = 'New List Item';

// Get the parent element
const list = document.getElementById('myList');

// Add the new item to the list
list.appendChild(newItem);

// You can also chain operations
const container = document.getElementById('container');
const paragraph = document.createElement('p');
paragraph.textContent = 'Added paragraph';
container.appendChild(paragraph);

The insertBefore() method inserts a new node before a specified reference node. It is called on the parent element and takes two arguments: the new node and the reference node.

javascript

// Create a new element
const newItem = document.createElement('li');
newItem.textContent = 'Inserted Item';

// Get the parent and reference elements
const list = document.getElementById('myList');
const secondItem = list.children[1];

// Insert newItem before secondItem
list.insertBefore(newItem, secondItem);

// If reference is null, it works like appendChild
list.insertBefore(newItem, null); // Adds at the end

The removeChild() method removes a specified child node from its parent and returns the removed node. You call it on the parent element and pass the child you want to remove.

javascript

// Get the parent and child elements
const list = document.getElementById('myList');
const itemToRemove = document.getElementById('item2');

// Remove the child from the parent
const removedItem = list.removeChild(itemToRemove);
console.log(removedItem); // The removed element

// Alternative: remove using parentNode
const element = document.getElementById('someElement');
element.parentNode.removeChild(element);

// Modern approach using remove() method
const item = document.getElementById('item3');
item.remove(); // Removes itself from the DOM

The replaceChild() method replaces a child node with a new node. It is called on the parent element and takes two arguments: the new node and the node to be replaced.

javascript

// Create a new element
const newHeading = document.createElement('h2');
newHeading.textContent = 'New Heading';

// Get the parent and the element to replace
const container = document.getElementById('container');
const oldHeading = document.getElementById('oldHeading');

// Replace old element with new element
const replacedElement = container.replaceChild(newHeading, oldHeading);
console.log(replacedElement); // The old element that was replaced

// Modern approach using replaceWith()
const oldParagraph = document.getElementById('oldPara');
const newParagraph = document.createElement('p');
newParagraph.textContent = 'Replacement paragraph';
oldParagraph.replaceWith(newParagraph);

The cloneNode() method creates a copy of a node. Pass true for a deep clone that includes all child elements, or false for a shallow clone that only copies the element itself.

javascript

// Get an element to clone
const originalCard = document.getElementById('card');

// Shallow clone (only the element, no children)
const shallowClone = originalCard.cloneNode(false);
console.log(shallowClone.children.length); // 0

// Deep clone (includes all children)
const deepClone = originalCard.cloneNode(true);
console.log(deepClone.children.length); // Same as original

// Add the clone to the page
document.body.appendChild(deepClone);

// Note: Cloned elements do not have event listeners
// You need to add event listeners to the clone separately

The addEventListener() method attaches an event handler to an element. It takes the event type as a string and a callback function that runs when the event occurs.

javascript

const button = document.getElementById('myButton');

// Add a click event listener
button.addEventListener('click', function() {
  console.log('Button was clicked!');
});

// Using arrow function
button.addEventListener('click', () => {
  console.log('Clicked with arrow function');
});

// Named function for reusability
function handleClick(event) {
  console.log('Event type:', event.type);
  console.log('Target element:', event.target);
}
button.addEventListener('click', handleClick);

// Multiple events on same element
const input = document.getElementById('myInput');
input.addEventListener('focus', () => console.log('Focused'));
input.addEventListener('blur', () => console.log('Blurred'));

The removeEventListener() method removes an event handler that was added with addEventListener(). You must pass the exact same function reference that was used when adding the listener.

javascript

const button = document.getElementById('myButton');

// Define the handler function
function handleClick() {
  console.log('Button clicked!');
}

// Add the event listener
button.addEventListener('click', handleClick);

// Remove the event listener (same function reference)
button.removeEventListener('click', handleClick);

// This will NOT work (different function reference)
button.addEventListener('click', function() { console.log('Hi'); });
button.removeEventListener('click', function() { console.log('Hi'); });
// The above removal fails because they are different function objects

// One-time listener using options
button.addEventListener('click', handleClick, { once: true });
// Automatically removed after first trigger

The parentElement property returns the parent element of a node. It returns null if the node has no parent or if the parent is not an element node.

javascript

// Get an element
const listItem = document.getElementById('item1');

// Access its parent element
const parentList = listItem.parentElement;
console.log(parentList.tagName); // 'UL' or 'OL'

// Chain to go up multiple levels
const grandparent = listItem.parentElement.parentElement;

// Check if parent exists before using
if (listItem.parentElement) {
  listItem.parentElement.style.border = '1px solid red';
}

// parentNode vs parentElement
// parentNode can return any node type
// parentElement only returns element nodes
const html = document.documentElement;
console.log(html.parentNode); // #document
console.log(html.parentElement); // null

The children property returns only element children, while childNodes returns all child nodes including text and comment nodes. Use children when you only need HTML elements.

javascript

const list = document.getElementById('myList');

// children returns HTMLCollection of element children only
console.log(list.children); // HTMLCollection of li elements
console.log(list.children.length); // Number of child elements
console.log(list.children[0]); // First child element

// childNodes returns NodeList including text nodes
console.log(list.childNodes); // NodeList with text nodes too
console.log(list.childNodes.length); // Usually more than children

// Useful properties
console.log(list.firstElementChild); // First child element
console.log(list.lastElementChild); // Last child element

// Loop through children
for (const child of list.children) {
  console.log(child.textContent);
}

The nextElementSibling and previousElementSibling properties return the next and previous sibling elements. They skip text nodes and only return element nodes, or null if there is no sibling.

javascript

const secondItem = document.getElementById('item2');

// Get next sibling element
const nextItem = secondItem.nextElementSibling;
console.log(nextItem.textContent); // Content of item3

// Get previous sibling element
const prevItem = secondItem.previousElementSibling;
console.log(prevItem.textContent); // Content of item1

// Check for siblings before accessing
if (secondItem.nextElementSibling) {
  secondItem.nextElementSibling.style.color = 'blue';
}

// Loop through all siblings
let sibling = secondItem.parentElement.firstElementChild;
while (sibling) {
  console.log(sibling.textContent);
  sibling = sibling.nextElementSibling;
}

The classList.toggle() method adds a class if it is not present, or removes it if it is. It returns true if the class was added and false if it was removed.

javascript

const box = document.getElementById('myBox');

// Toggle a class
box.classList.toggle('active');
// If 'active' was present, it is removed
// If 'active' was not present, it is added

// Check the return value
const wasAdded = box.classList.toggle('highlight');
console.log(wasAdded); // true if added, false if removed

// Force add or remove with second argument
box.classList.toggle('visible', true); // Always adds
box.classList.toggle('visible', false); // Always removes

// Common use case: toggle on click
const button = document.getElementById('toggleBtn');
button.addEventListener('click', () => {
  box.classList.toggle('dark-mode');
});