Traversing Ancestors
In this page:
$(selector).parent();
$(selector).parents(filter);
$(selector).closest(selector);
parent()
.parent() walks up exactly one level in the DOM tree and returns the immediate parent of each selected element. It never looks further up than one level, even if there's no match -- it simply won't skip ahead to a grandparent.
Example: parent()
<!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">
<div id="grandparent"><div id="parent"><p id="child">Text</p></div></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text(String($("#child").parent().attr("id")));
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
parents()
parents() selects all matching ancestors going all the way up to the document root, not just the immediate parent. You can optionally pass a selector to filter which ancestors in that whole chain get included.
Example: parents()
<!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">
<div id="grandparent"><div id="parent"><p id="child">Text</p></div></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#child").parents().length);
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
parentsUntil()
parentsUntil() travels upward collecting ancestors, but stops just before reaching a chosen ancestor you specify, rather than going all the way to the root. This is useful when you know exactly where the walk should stop, like up to a specific container.
Example: parentsUntil()
<!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">
<div id="stop"><div id="mid"><p id="child">Text</p></div></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#child").parentsUntil("#stop").length);
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
closest()
closest() finds the nearest matching ancestor starting from the element itself and moving upward, stopping at the very first match it finds. Unlike parents(), it stops as soon as it finds one match instead of collecting every ancestor that matches.
Example: closest()
<!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">
<div class="card"><p id="child">Text</p></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
$("#runBtn").click(function() {
$("#output").text($("#child").closest(".card").length);
});
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
});
</script>
</body>
</html>
Ancestor Practice
Ancestor methods are useful for changing a container based on a clicked or selected element inside it, such as finding the enclosing list item when a button inside it is clicked. closest() in particular is the standard tool for this in event-delegation patterns.
Example: Ancestor Practice
<!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="resetBtn">Reset</button>
<section id="demo">
<li class="task"><button id="del">Delete</button></li>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
$("#del").on("click", function() {
$(this).closest(".task").remove();
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
- Using
.parents()when you only want the direct parent, since it returns every ancestor up to<html>;.parent()gives one level. - Assuming
.parentsUntil("#top")includes#top, when it stops just before it. - Expecting
.parent()to return the ancestor with a certain class;.closest(".class")is the method that searches upward.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: