Introduction to DOM Traversing
In this page:
$("selector").traversalMethod();
$("selector").children();
$("selector").parent();
$("selector").siblings();
What Is Traversing?
Once you've selected one element, traversal methods let you step to its parents, children, or siblings instead of writing a brand-new selector. This is often simpler and more reliable than trying to describe a related element's position from scratch with CSS selector syntax.
Example: What Is Traversing?
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
#box { background:steelblue; color:#1a1a1a; padding:10px; border-radius:4px; display:inline-block; margin:10px 0; }
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="runBtn">Run</button>
<button id="resetBtn">Reset</button>
<section id="demo">
<div id="box"><p>Child paragraph</p></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#box").children().length);
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
Using find()
Use find() when you want matching elements deeper inside a selected element, searching through all of its descendants regardless of nesting depth. It works like running a fresh selector, but scoped to only search within the elements you've already selected.
Example: Using find()
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
#box { background:steelblue; color:#1a1a1a; padding:10px; border-radius:4px; display:inline-block; margin:10px 0; }
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="runBtn">Run</button>
<button id="resetBtn">Reset</button>
<section id="demo">
<div id="box"><ul><li>Item</li></ul></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#box").find("li").length);
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
Using first() and last()
first() and last() narrow a selection down to just its first or last matched element, which is useful after a broader selection like find() or filter() returns several results. Both return a new jQuery object containing at most one element.
Example: Using first() and last()
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="runBtn">Run</button>
<button id="resetBtn">Reset</button>
<section id="demo">
<ul id="list"><li>One</li><li>Two</li><li>Three</li></ul>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#list li").first().text() + " " + $("#list li").last().text());
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
Chaining Traversal
Traversal methods can be chained together -- for example, finding a container, then its children, then filtering those -- building up a precise selection step by step. This keeps code short by avoiding separate selector strings for every intermediate step.
Example: Chaining Traversal
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
#box { background:steelblue; color:#1a1a1a; padding:10px; border-radius:4px; display:inline-block; margin:10px 0; }
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="runBtn">Run</button>
<button id="resetBtn">Reset</button>
<section id="demo">
<div id="box"><ul><li class="active">One</li><li>Two</li></ul></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#box").find("li").filter(".active").text());
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
Practical Traversing
DOM traversal is especially useful when elements are related structurally but don't have unique IDs or classes to select directly, such as finding 'the button next to whichever input triggered an event'. It lets your code follow the actual DOM relationships instead of hardcoding selectors.
Example: Practical Traversing
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
.btn { display:inline-block; padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border-radius:4px; cursor:pointer; font:13px sans-serif; }
#resetBtn.btn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<span id="resetBtn" class="btn" role="button">Reset</span>
<section id="demo">
<div class="row"><input id="field"><button>Next</button></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
$("#field").closest(".row").find("button").on("click", function() {
$("#output").append($("<div>").text("Next clicked"));
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
- Using
.find("li")when you want direct children only, since it searches all descendants and.children()looks one level down. - Forgetting that traversal methods return new jQuery objects and ignoring the result, as in
$("#box").children();on its own line. - Calling
.first()on an empty selection and expecting an element, when it returns an empty jQuery object with no error.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: