Core jQuery Concepts & DOM Manipulation

SA
StudyAI Editorial
Reviewed by StudyAI tutors
· Published Updated

From the I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic curriculum

Core jQuery Concepts & DOM Manipulation

TL;DR

You'll understand how jQuery wraps DOM elements, why chaining works, and the real difference between .html(), .text(), and .val(). You'll know event delegation cold — the #1 jQuery interview question. You'll also see common performance traps interviewers love to probe, like re-querying the DOM in loops.

1. The Mental Model

jQuery takes raw DOM elements and wraps them in a special array-like object with dozens of built-in methods. Every jQuery method (unless it explicitly returns data) returns that same wrapped object, which is why you can chain .addClass().fadeIn().on() in one line. Selecting is expensive; jQuery objects are cheap to reuse once cached. The core idea: jQuery is a wrapper around a set of matched DOM elements, and almost everything is designed to be chained or cached.

2. The Core Material

2.1 Selection, the jQuery Object, and Chaining

Detailed view of a sturdy black metal chain outdoors on a blurred background.
Photo by Suki Lee on Pexels

$('selector') runs a CSS-style query against the DOM and returns a jQuery object — not a raw DOM node, not an array, but an array-like structure with indexed elements ($('.item')[0] gives you the raw DOM node) plus jQuery methods attached.

const $items = $('.item');       // jQuery object, cached
console.log($items.length);      // number of matches
console.log($items[0]);          // raw DOM element
console.log($items.get(0));      // same thing, official API

Chaining works because most jQuery methods return this; internally — this being the same wrapped set. That's why this works:

$('.alert')
  .addClass('visible')
  .css('color', 'red')
  .fadeIn(200)
  .delay(3000)
  .fadeOut(200);

Interviewers test whether you know which methods break the chain. Getter methods like .text() (no args), .val() (no args), .html() (no args), .attr('href') (no args), and .data('key') return the value, not the jQuery object — chaining stops there. Setter versions (with an argument) return the jQuery object, so chaining continues.

$('#name').text();              // returns a string — chain broken
$('#name').text('Alice').fadeIn(); // returns jQuery object — chain continues

2.2 DOM Manipulation: html() vs text() vs val() vs append/prepend

Close-up of HTML and JavaScript code on a computer screen in Visual Studio Code.
Photo by Antonio Batinić on Pexels

This trio gets confused constantly, and interviewers ask "what's the difference" almost as a warm-up.

  • .html() — gets/sets the inner HTML (parses tags). Vulnerable to XSS if you inject unsanitized user input.
  • .text() — gets/sets plain text, escapes HTML entities automatically. Safe against injection.
  • .val() — gets/sets the value of form elements (input, select, textarea). .html()/.text() don't work on form values.
$('#box').html('<b>Bold</b>');   // renders bold text
$('#box').text('<b>Bold</b>');   // renders literal string "<b>Bold</b>"
$('#username').val();            // reads current input value

For inserting elements, know the four directional methods:

$('#list').append('<li>last</li>');    // inside, at the end
$('#list').prepend('<li>first</li>');  // inside, at the start
$('#list').after('<p>sibling after</p>');  // outside, after element
$('#list').before('<p>sibling before</p>'); // outside, before element

Reverse direction versions exist too: .appendTo(), .prependTo(), .insertAfter(), .insertBefore() — same operation, but the target is the argument instead of the caller. Useful when moving existing elements rather than creating new ones:

$('#existing-item').appendTo('#new-list'); // moves the actual node

2.3 Event Binding and Delegation

Flat lay of business conference materials including name tags, program, notebook, and pen.
Photo by Pavel Danilyuk on Pexels

The most important interview topic in this note. Direct binding with .on('click', handler) only attaches to elements that exist at bind time. Elements added later via AJAX or .append() won't have the handler — a classic bug.

// BROKEN for dynamically added items
$('.delete-btn').on('click', function() {
  $(this).closest('li').remove();
});
$('#list').append('<li>New <button class="delete-btn">X</button></li>');
// clicking the new button does nothing

Event delegation fixes this by attaching the listener to a stable ancestor and filtering by selector when the event bubbles up:

$('#list').on('click', '.delete-btn', function() {
  $(this).closest('li').remove();
});
// works for ANY .delete-btn, including ones added after this line runs

Why it works: DOM events bubble up the tree. #list catches the click, checks if event.target (or an ancestor of it) matches .delete-btn, and only then runs the handler. This is also far more memory-efficient than binding 1,000 individual click handlers to 1,000 list items — you get ONE handler total.

flowchart TD
    A["User clicks button.delete-btn"] --> B["Click event fires on button"]
    B --> C["Event bubbles up DOM tree"]
    C --> D["Reaches #list (has delegated listener)"]
    D --> E{"Does event.target match '.delete-btn'?"}
    E -- Yes --> F["Handler runs, li.remove() executes"]
    E -- No --> G["Event ignored, continues bubbling"]

Also know .on() replaced .bind(), .live(), and .delegate() — all deprecated. .on() unifies direct and delegated binding depending on whether you pass a selector as the second argument.

3. Worked Example

Task: Build a to-do list where items can be added dynamically, marked complete on click, and removed with a delete button — all handled efficiently with jQuery.

<ul id="todo-list">
  <li>Buy milk <button class="del">X</button></li>
</ul>
<input id="new-todo" type="text" placeholder="New task">
<button id="add-btn">Add</button>
$(function() {
  // 1. Add new items dynamically
  $('#add-btn').on('click', function() {
    const text = $('#new-todo').val().trim();
    if (text === '') return;

    // .text() used here, NOT .html(), to prevent XSS from user input
    const $li = $('<li>').text(text).append(
      $('<button>').addClass('del').text('X')
    );
    $('#todo-list').append($li);
    $('#new-todo').val(''); // clear input, chain not needed here
  });

  // 2. Delegated event for marking complete — works on items added AFTER page load
  $('#todo-list').on('click', 'li', function(e) {
    // don't toggle complete if the delete button itself was clicked
    if ($(e.target).is('.del')) return;
    $(this).toggleClass('completed');
  });

  // 3. Delegated event for deletion
  $('#todo-list').on('click', '.del', function(e) {
    e.stopPropagation(); // prevent bubbling into the li's click handler above
    $(this).closest('li').remove();
  });
});

Walking through what's actually happening: $(function(){...})` is shorthand for `$(document).ready(), ensuring the DOM exists before we bind anything. The add-button handler reads .val() from the text input (not .text() or .html(), since it's a form field), builds a new <li> using .text() for the user-supplied string (never .html() — that would let someone type <img src=x onerror=alert(1)> and execute it), and appends a nested button built with jQuery's element constructor $('<button>').

Both click handlers on #todo-list are delegated — bound once on the parent, filtered by selector (li and .del respectively). This means new to-do items added after page load are automatically clickable and deletable with zero extra binding code. The e.stopPropagation() call is the subtle but critical piece: without it, clicking delete would also bubble up and trigger the "mark complete" toggle on the same click, because both handlers live on the same ancestor and both match the bubbling event.

This example demonstrates every core concept in one flow: selection and caching, .val() vs .text() correctness, dynamic element creation, and delegation solving the "elements added later" problem — while also showing why event propagation control matters when handlers overlap.

4. Production Pitfalls & Best Practices

4.1 Real-World Best Practices

Captivating view of New York City skyline featuring a prominent globe sculpture and tall skyscrapers.
Photo by Following NYC on Pexels

  • Cache selectors in variables. const $rows = $('.row'); once, reuse it — don't call $('.row') five times in the same function; each call re-walks the DOM.
  • Prefer delegation for any list that can grow. Comments, notifications, search results — always bind on a stable container.
  • Use .text() by default for user-generated content; only use .html() when you control the source or have sanitized it (e.g., with DOMPurify).
  • Batch DOM writes. Build HTML as a string or use a detached fragment, then insert once, instead of calling .append() in a loop (each call can trigger reflow).
  • Namespace your events ('click.todoApp') so you can unbind precisely later without nuking other plugins' handlers on the same element.
  • Use .prop() for booleans, .attr() for HTML attributes. checked, disabled, selected should use .prop().attr() gives inconsistent results across browsers for these.

4.2 Common Bugs & Anti-Patterns

Bug 1: Re-querying inside a loop

// BAD — queries the DOM on every iteration
for (let i = 0; i < 100; i++) {
  $('#status').append('<p>Item ' + i + '</p>');
}
// FIXED — build once, insert once
let html = '';
for (let i = 0; i < 100; i++) {
  html += `<p>Item ${i}</p>`;
}
$('#status').append(html);

Bug 2: Direct binding on dynamic content

// BAD — new .row elements added later get no handler
$('.row').on('click', handler);
// FIXED — delegate from a static parent
$('#table-body').on('click', '.row', handler);

Bug 3: Using .attr('checked') to read checkbox state

// BAD — returns "checked" string or undefined, inconsistent
if ($('#agree').attr('checked')) { ... }
// FIXED — .prop() gives a real boolean
if ($('#agree').prop('checked')) { ... }

Bug 4: Injecting raw user input with .html()

// BAD — XSS vulnerability
$('#comment').html(userInput);
// FIXED — escapes automatically
$('#comment').text(userInput);

4.3 When to Use What

Situation Right Tool Why
Reading/writing form input value .val() .html()/.text() don't touch form values
Rendering trusted HTML (server-templated) .html() Need actual tag parsing
Rendering user-typed text .text() Auto-escapes, prevents XSS
Elements added after page load need handlers .on() with delegation Direct .on() misses future elements
Toggling checkbox/disabled/selected state .prop() Returns real booleans, cross-browser safe
Reading a static HTML attribute (e.g. data-id, href) .attr() .prop() is for DOM properties, not raw attributes

5. Now Try It

Write the jQuery code (no HTML boilerplate needed, assume a <ul id="cart"> exists) to: (1) delegate a click handler on .remove-item buttons inside #cart that removes the parent <li>, and (2) delegate a handler on .qty-input (a text field inside each <li>) that, on change, reads the new value with the correct method and logs it — without breaking when new <li> items are added dynamically after page load.

Success looks like: your code uses .on() delegation (not direct binding) for both handlers, uses .val() (not .text()) to read the quantity input, and correctly scopes .remove-item deletion to .closest('li') rather than removing the wrong element.

Frequently asked about Core jQuery Concepts & DOM Manipulation

You'll understand how jQuery wraps DOM elements, why chaining works, and the real difference between .html(), .text(), and .val(). You'll know event delegation cold — the #1 jQuery interview question. Read the full notes above for the details.

Core jQuery Concepts & DOM Manipulation is a core topic in I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic. Most exam papers test it via a mix of definitions, worked examples, and applied problems. The notes above cover the high-yield sub-topics, common pitfalls, and the kind of questions examiners typically set.

Yes. Every note in the StudyAI Campus Hub is free to read. Create a free account if you want to clone the full plan, generate your own notes from your textbook, or get AI-powered practice quizzes and flashcards.

More from I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic


Get the full I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic curriculum

Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.

Create Free Account