Introduction
jQuery is a lightweight JavaScript library that simplifies HTML document traversal, event handling, animation, and Ajax interactions. Since its introduction, it has remained a popular choice for developers seeking to build interactive web pages efficiently.
This guide covers fundamental jQuery concepts including element selection using CSS selectors, DOM traversal techniques, and event handling mechanisms. You'll learn how to manipulate page content, respond to user interactions, and leverage jQuery's chainable API for concise code.
Setting Up jQuery
Downloading the Library
To use jQuery, you need a copy of the library file. The official website always hosts the latest stable version. Since JavaScript is an interpreted language, no compilation is required—simply include the library file via a <script> tag in your HTML document.
Content Delivery Networks (CDNs) like Google, Microsoft, and the official jQuery CDN provide hosted versions that offer performance benefits through global distribution and browser caching.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<link rel="stylesheet" href="styles.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<h1>Through the Looking-Glass</h1>
<div class="author">by Lewis Carroll</div>
<div class="chapter" id="chapter-1">
<h2>1. Looking-Glass House</h2>
<p>Content goes here...</p>
<div class="poem">
<div class="poem-stanza">JABBERWOCKY content...</div>
</div>
</div>
</body>
</html>
Basic CSS Styling
body {
background-color: #fff;
color: #000;
font-family: Helvetica, Arial, sans-serif;
}
h1, h2, h3 {
margin-bottom: .2em;
}
.poem {
margin: 0 2em;
}
.highlight {
background-color: #ccc;
border: 1px solid #888;
font-style: italic;
margin: 0.5em 0;
padding: 0.5em;
}
Your First jQuery Script
The Document Ready Handler
The $() function serves multiple purposes in jQuery. When passed a function, it registers that function to execute when the DOM is fully loaded:
$(() => {
$('div.poem-stanza').addClass('highlight');
});
This pattern ensures your code runs only after the HTML structure is available for manipulation. The arrow function syntax provides a concise callback, though traditional function() syntax works identically.
Understanding the Selection
The $('div.poem-stanza') expression uses the $() function with a CSS selector string. This returns a jQuery object containing all matching elements—in this case, all <div> elements with the class poem-stanza.
The .addClass() method then applies the highlight class to these elements. Notice that no explicit loop is required; jQuery automatically iterates through all matched elements.
Pure JavaScript Comparison
Achieving the same result without jQuery requires significantly more code:
window.addEventListener('load', () => {
const divs = document.getElementsByTagName('div');
const hasClass = (elem, cls) =>
new RegExp(` ${cls} `).test(` ${elem.className} `);
for (let div of divs) {
if (hasClass(div, 'poem-stanza') && !hasClass(div, 'highlight')) {
div.className += ' highlight';
}
}
});
The jQuery version is shorter, more readable, and handles edge cases like respecting existing event handlers.
Element Selection with jQuery
Understanding the DOM
The Document Object Model (DOM) represents HTML as a tree structure. Elements have relationships: parents, children, siblings, ancestors, and descendants.
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div>
<p>First paragraph.</p>
<p>Second paragraph.</p>
<p>Third paragraph.</p>
</div>
</body>
</html>
In this hierarchy, <html> is the ancestor of all elements, while <head> and <body> are siblings. The <p> elements are children of <div> and descendants of <html>.
The Three Building Blocks
Basic CSS selectors form the foundation of jQuery selection:
| Selector Type | Syntax | Description |
|---|---|---|
| Tag Name | $('p') |
Selects all paragraphs |
| ID | $('#element-id') |
Selects the single element with this ID |
| Class | $('.class-name') |
Selects all elements with this class |
Child Combinators
To select only direct children, use the > combinator:
$(() => {
$('#selected-plays > li').addClass('horizontal');
});
This targets only top-level list items within #selected-plays, not nested items.
The :not() Pseudo-Class
Exclude elements matching a selector using :not():
$(() => {
$('#selected-plays > li').addClass('horizontal');
$('#selected-plays li:not(.horizontal)').addClass('sub-level');
});
.horizontal {
float: left;
list-style: none;
margin: 10px;
}
.sub-level {
background: #ccc;
}
Attribute Selectors
Attribute selectors match elements based on their HTML attributes:
$('img[alt]')
This selects all images with an alt attribute.
Wildcard Matching
Modify selector behavior with special characters:
$(() => {
$('a[href^="mailto:"]').addClass('mailto');
$('a[href$=".pdf"]').addClass('pdflink');
$('a[href^="http"][href*="henry"]').addClass('henrylink');
});
^=matches the beginning$=matches the end*=matches anywhere
a { color: #00c; }
a.mailto {
background: url(images/email.png) no-repeat right top;
padding-right: 18px;
}
a.pdflink {
background: url(images/pdf.png) no-repeat right top;
padding-right: 18px;
}
a.henrylink {
background-color: #fff;
padding: 2px;
border: 1px solid #000;
}
Custom jQuery Selectors
jQuery extends CSS with custom selectors:
$('div.horizontal:eq(1)')
The :eq() selector uses zero-based indexing. This selects the second div.horizontal element.
Alternating Row Styling
$(() => {
$('tr:even').addClass('alt');
});
Note that :even and :odd also use zero-based indexing, so the first row (index 0) is considered even.
For reliable row striping across multiple tables, use :nth-child():
$(() => {
$('tr:nth-child(odd)').addClass('alt');
});
This selector counts relative to the parent element and accepts odd, even, or numeric values.
Content-Based Selection
$(() => {
$('td:contains(Henry)').addClass('highlight');
});
The :contains() selector is case-sensitive and can impact performance on large documents.
Form Element Selectors
jQuery provides convenient selectors for form elements:
| Selector | Matches |
|---|---|
:input |
All input, textarea, select, and button elements |
:button |
Button elements and inputs with type="button" |
:enabled |
Enabled form elements |
:disabled |
Disabled form elements |
:checked |
Checked checkboxes and radio buttons |
:selected |
Selected option elements |
DOM Traversal Methods
Filtering with .filter()
The .filter() method narrows down a selection:
$('a')
.filter((i, a) =>
a.hostname && a.hostname !== location.hostname
)
.addClass('external');
This adds the external class to all links pointing to external domains. The callback receives the index and element, returning true to keep the element or false to exclude it.
Sibling Navigation
Move between sibling elements:
$(() => {
$('td:contains(Henry)')
.next()
.addClass('highlight');
});
Related methods include:
.nextAll()- all following siblings.prev()- immediately preceding sibling.prevAll()- all preceding siblings.siblings()- all siblings.addBack()- include the original selection
Parent and Children
Traverse up and down the DOM tree:
$(() => {
$('td:contains(Henry)')
.parent()
.children()
.addClass('highlight');
});
This selects the parent <tr> of each cell containing "Henry", then adds the class to all its children cells.
Chaining
jQuery methods return the jQuery object, enabling method chaining:
$('td:contains(Henry)')
.parent()
.find('td:eq(1)')
.addClass('highlight')
.end()
.find('td:eq(2)')
.addClass('highlight');
The .end() method returns to the previous selection, allowing you to chain different traversal operations.
Modern Iteration: for...of
jQuery 3 supports iterating over collections using for...of:
const titles = [];
for (let td of $('td')) {
if (td.textContent.startsWith('H')) {
titles.push(td.textContent);
}
}
This extracts text from all cells starting with "H".
Accessing DOM Elements
When you need the underlying DOM element instead of the jQuery wrapper:
$('#my-element').get(0).tagName;
// Shorthand
$('#my-element')[0].tagName;
Event Handling
Document Ready Alternatives
The $(() => {}) pattern executes when the DOM is ready but before images finish loading, whereas window.onload waits for all resources:
$(() => {
// DOM ready, can manipulate elements
});
Click Events
The .on() method attaches event handlers:
$(() => {
$('#switcher-large')
.on('click', () => {
$('body').addClass('large');
});
});
Shortcut methods like .click() provide a simpler syntax for common events.
The Event Object
Event handlers receive an event object with useful properties:
$('#switcher')
.on('click', function(event) {
if (event.target === this) {
$(this)
.children('button')
.toggleClass('hidden');
}
});
The this Context
Inside event handlers, this refers to the DOM element that triggered the event:
$(() => {
$('#switcher button')
.on('click', function() {
$(this).addClass('selected');
});
});
Note: Arrow functions don't bind this lexically, so use regular functions for event handlers that need access to the triggering element.
Event Propagation
Events bubble up through the DOM hierarchy. The .stopPropagation() method prevents this:
$('#switcher button')
.on('click', (e) => {
// Handle button click
e.stopPropagation();
});
Event Delegation
Instead of attaching handlers to individual elements, attach to a parent and let events bubble up:
$('#switcher')
.on('click', 'button', (e) => {
const styleName = e.target.id.split('-')[1];
$('body')
.removeClass()
.addClass(styleName);
});
The second parameter to .on() filters events by selector, useful for handling clicks on dynamically added elements.
Preventing Default Actions
Stop link navigation or form submission:
$('a.disabled')
.on('click', (e) => {
e.preventDefault();
});
Hover Effects
$('#switcher h3')
.hover(
() => $(this).addClass('hover'),
() => $(this).removeClass('hover')
);
The .hover() method takes two functions: the first for mouseenter, the second for mouseleave.
Toggle Classes
$('#switcher h3')
.on('click', () => {
$(this)
.siblings('button')
.toggleClass('hidden');
});
The .toggleClass() method adds a class if missing, or removes it if present.
Unbinding Events
Remove event handlers with .off():
$('#switcher').off('click');
Use namespaced events for selective unbinding:
$('#switcher')
.on('click.collapse', handleCollapse);
$('#switcher-narrow, #switcher-large')
.on('click', () => {
$('#switcher').off('click.collapse');
});
One-Time Events
$('#switcher').one('click', handler);
This attaches a handler that executes only once.
Triggering Events
Simulate user interactions programmatically:
$('#switcher').trigger('click');
// Shorthand
$('#switcher').click();
Keyboard Events
const shortcuts = {
D: 'default',
N: 'narrow',
L: 'large'
};
$(document)
.on('keyup', (e) => {
const key = String.fromCharCode(e.which);
if (key in shortcuts) {
$(`#switcher-${shortcuts[key]}`).click();
}
});
Complete Example: Style Switcher
$(() => {
const applyStyle = (styleName) => {
$('body')
.removeClass()
.addClass(styleName);
$('#switcher button').removeClass('selected');
$(`#switcher-${styleName}`).addClass('selected');
};
const styleMap = { D: 'default', N: 'narrow', L: 'large' };
$('#switcher-default').addClass('selected');
$('#switcher')
.on('click', 'button', (e) => {
const style = e.target.id.split('-')[1];
applyStyle(style);
})
.on('click', (e) => {
if ($(e.target).is(':not(button)')) {
$(this)
.children('button')
.toggleClass('hidden');
}
})
.click();
$(document)
.on('keyup', (e) => {
const letter = String.fromCharCode(e.which);
if (letter in styleMap) {
applyStyle(styleMap[letter]);
}
});
});
Exercises
- Add a
specialclass to all second-level<li>elements in nested lists. - Apply a
yearclass to all cells in the third column of a table. - Add the
specialclass to the table row containing the word "Tragedy". - Select all
<li>elements containing links (<a>) and add classafterlinkto the sibling<li>following each selected item. - Apply the class
tragedyto the nearest ancestor<ul>of any.pdflink. - Apply the
selectedstyle when clicking on "Charles Dickens". - Toggle chapter text visibility on double-clicking chapter titles (
<h3 class="chapter-title">). - Cycle through
bodyclasses when the right arrow key (key code 39) is pressed. - Log mouse coordinates when moving over any paragraph using
console.log(). - Track mouse events anywhere on the page using
.mousedown()and.mouseup(). Addhiddenclass to all paragraphs if the mouse is released above the press point, remove it if released below.