Skip to content
beginnerPhase 34 · DOM

Creating Elements

Dynamically create DOM elements with createElement and insertAdjacentHTML.

30m
0 problems
Topic Progress0%

createElement

document.createElement() creates a new element node.

Basic Usage

// Create element
const div = document.createElement('div');
const img = document.createElement('img');
const button = document.createElement('button');

// Set properties before adding to DOM
div.className = 'container';
div.id = 'main';
button.textContent = 'Click me';
img.src = 'photo.jpg';
img.alt = 'A photo';

Building Complex Elements

function createCard(title, content, imageUrl) {
  const card = document.createElement('div');
  card.className = 'card';
  
  const image = document.createElement('img');
  image.src = imageUrl;
  image.alt = title;
  
  const heading = document.createElement('h3');
  heading.textContent = title;
  
  const text = document.createElement('p');
  text.textContent = content;
  
  card.appendChild(image);
  card.appendChild(heading);
  card.appendChild(text);
  
  return card;
}

// Usage
const myCard = createCard(
  'Hello',
  'This is a card',
  'image.jpg'
);
document.body.appendChild(myCard);

Setting Attributes

const link = document.createElement('a');

// Method 1: setAttribute
link.setAttribute('href', 'https://example.com');
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener');

// Method 2: Direct property
link.href = 'https://example.com';
link.target = '_blank';

// Method 3: dataset
link.dataset.id = '123';
link.dataset.action = 'view';
// Creates: data-id="123" data-action="view"

Adding to DOM

const container = document.querySelector('.container');
const newElement = document.createElement('p');
newElement.textContent = 'New paragraph';

// appendChild - adds at end
container.appendChild(newElement);

// insertBefore - adds before reference
container.insertBefore(newElement, referenceElement);

// Modern methods
container.append(newElement); // Can add multiple
container.prepend(newElement); // Adds at start
newElement.before(referenceElement); // Before reference
newElement.after(referenceElement); // After reference

innerHTML

innerHTML gets or sets the HTML content of an element.

Reading innerHTML

const container = document.querySelector('.container');
console.log(container.innerHTML);
// Returns all child HTML as a string

Setting innerHTML

// Replace all content
container.innerHTML = '<h1>New Content</h1><p>New paragraph</p>';

// Append content
container.innerHTML += '<p>Appended</p>';

// WARNING: This destroys existing elements and event listeners!
const existing = container.querySelector('button');
existing.addEventListener('click', handler);

container.innerHTML = 'New content'; // existing button is destroyed!
// handler is lost

XSS Vulnerability

// DANGEROUS - Never use with user input!
const userInput = '<script>alert("XSS")</script>';
container.innerHTML = userInput; // Executes script!

// SAFE - Use textContent for user input
container.textContent = userInput; // Shows as text

// SAFE - Sanitize before using innerHTML
function sanitize(html) {
  const div = document.createElement('div');
  div.textContent = html;
  return div.innerHTML;
}
container.innerHTML = sanitize(userInput);

When to Use innerHTML

// GOOD: Static, known content
container.innerHTML = `
  <div class="card">
    <h2>${title}</h2>
    <p>${content}</p>
  </div>
`;

// BETTER: Use DOM methods for dynamic content
const card = document.createElement('div');
card.className = 'card';
const h2 = document.createElement('h2');
h2.textContent = title;
card.appendChild(h2);
container.appendChild(card);

Performance Consideration

// BAD: Multiple innerHTML modifications
for (let i = 0; i < 100; i++) {
  container.innerHTML += `<div>Item ${i}</div>`; // Re-parses each time!
}

// GOOD: Build string, set once
let html = '';
for (let i = 0; i < 100; i++) {
  html += `<div>Item ${i}</div>`;
}
container.innerHTML = html; // Parse once

// BETTER: Use DocumentFragment
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const div = document.createElement('div');
  div.textContent = `Item ${i}`;
  fragment.appendChild(div);
}
container.appendChild(fragment); // Single DOM update

insertAdjacentHTML

insertAdjacentHTML parses HTML and inserts it at a specified position relative to the element.

Positions

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

// beforebegin: Before the element itself
// afterbegin: Just inside the element, before its first child
// beforeend: Just inside the element, after its last child
// afterend: After the element itself

const html = '<div class="new">New content</div>';

element.insertAdjacentHTML('beforebegin', html); // Before element
element.insertAdjacentHTML('afterbegin', html);  // First child
element.insertAdjacentHTML('beforeend', html);   // Last child
element.insertAdjacentHTML('afterend', html);    // After element

Visual Example

<!-- beforebegin -->
<div class="target">
  <!-- afterbegin -->
  Existing content
  <!-- beforeend -->
</div>
<!-- afterend -->

Comparison with innerHTML

// innerHTML replaces ALL content
container.innerHTML = '<p>New</p>'; // Destroys existing

// insertAdjacentHTML adds without destroying
container.insertAdjacentHTML('beforeend', '<p>New</p>'); // Preserves existing

// insertAdjacentHTML doesn't affect existing elements
const existing = container.querySelector('button');
existing.addEventListener('click', handler);

container.insertAdjacentHTML('beforeend', '<p>New</p>');
// existing button and its listener preserved!

Practical Example

function addMessage(text, type = 'info') {
  const messages = document.getElementById('messages');
  
  const html = `
    <div class="message message-${type}">
      <span>${text}</span>
      <button class="close">&times;</button>
    </div>
  `;
  
  messages.insertAdjacentHTML('beforeend', html);
}

// Add message without destroying existing ones
addMessage('Hello!', 'info');
addMessage('Error!', 'error');

Performance

// insertAdjacentHTML is often faster than innerHTML
// because it doesn't destroy existing content

// For adding multiple elements:
// 1. Build HTML string
// 2. Use insertAdjacentHTML once
// 3. Much faster than multiple appendChild calls

let html = '';
for (let i = 0; i < 100; i++) {
  html += `<div>Item ${i}</div>`;
}
container.insertAdjacentHTML('beforeend', html);

Practice Problems

0/3solved
Build Creating Elements Component

Create a reusable React component implementing Creating Elements. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Creating Elements Testing

Write unit and integration tests for Creating Elements using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Creating Elements Performance

Optimize Creating Elements for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What does document.createElement() return?

Question 1 options

2. Why is innerHTML dangerous with user input?

Question 2 options

3. What position does 'beforeend' insert at?

Question 3 options

4. What's the benefit of insertAdjacentHTML over innerHTML?

Question 4 options

Flashcards

Question

What does createElement return?

Answer

An element node in memory, not yet added to the DOM. Must use appendChild or similar to add it.

Question

Why avoid innerHTML with user input?

Answer

It can execute malicious scripts (XSS attacks). Use textContent for user-generated content.

Question

What are insertAdjacentHTML positions?

Answer

beforebegin, afterbegin, beforeend, afterend - relative to the target element.

Question

innerHTML vs insertAdjacentHTML?

Answer

innerHTML replaces all content (destroys listeners). insertAdjacentHTML adds at position (preserves existing).

Question

What is Creating Elements?

Answer

Creating Elements is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.createElement creates elements in memory, not in DOM
  • 2.innerHTML replaces all content and destroys listeners
  • 3.insertAdjacentHTML adds content without destroying existing
  • 4.Never use innerHTML with unsanitized user input
  • 5.Use DocumentFragment for batch DOM updates

Interview Tips

  • Show how to create complex elements programmatically
  • Explain XSS risks with innerHTML
  • Compare innerHTML vs insertAdjacentHTML vs appendChild
  • Demonstrate DocumentFragment for performance

Cheat Sheet

Creating Elements Cheat Sheet

createElement

const el = document.createElement('div');
el.className = 'my-class';
el.textContent = 'Hello';

Adding to DOM

parent.appendChild(el);      // At end
parent.prepend(el);          // At start
el.before(ref);              // Before reference
el.after(ref);               // After reference

innerHTML

el.innerHTML = '<p>New</p>'; // Replaces all
el.innerHTML += '<p>Add</p>'; // Appends

insertAdjacentHTML

el.insertAdjacentHTML('beforeend', html);

Safety

  • Never use innerHTML with user input
  • Use textContent for user content
  • Sanitize HTML if needed