jQuery .end() Method

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Selection stack

What You’ll Learn

The .end() traversing method pops jQuery’s internal selection stack and restores the matched set from before the most recent filtering step. This tutorial covers the official two-list .find() chain, paragraph border demo, stack visualization, compare with .addBack(), and nested .end() patterns.

01

Syntax

.end()

02

Pop stack

One level

03

After find

Go back

04

Chaining

No variables

05

vs addBack

Restore vs merge

06

Since 1.0

Core API

Introduction

jQuery chaining is powerful: start with a selector, narrow with .find(), .filter(), or .children(), then style the result. But what if the next step needs the original matched set — not the narrowed subset? That is where .end() comes in.

Available since jQuery 1.0, .end() ends the most recent filtering operation and returns the collection to its previous state. Think of it as closing a nested block: each filtering method pushes a new set onto an internal stack, and .end() pops it back off.

Understanding the .end() Method

Most jQuery DOM traversal methods produce a new jQuery object matching a different set of elements. jQuery maintains a stack of previous sets inside the object. When you call .end(), the current set is discarded and replaced by the set from one level earlier.

.end() takes no arguments and does not modify the DOM — it only changes which elements the jQuery object refers to. It is most useful during method chaining when you want to avoid storing intermediate collections in variables.

💡
Beginner Tip

Picture nested boxes: .find() opens an inner box; .end() closes it and returns to the outer box. Multiple .end() calls close multiple levels.

📝 Syntax

General form of .end:

jQuery
.end()

Parameters

  • None — .end() does not accept any arguments.

Return value

  • The previous jQuery object from the internal stack — the matched set before the most recent filtering operation.

Official jQuery API two-list chain

jQuery
$( "ul.first" )
  .find( ".foo" )
  .css( "background-color", "red" )
  .end()
  .find( ".bar" )
  .css( "background-color", "green" );
// .foo red inside first ul only
// .bar green inside first ul only (end restored ul.first)

⚡ Quick Reference

GoalCode
Restore set after .find()$("ul").find("li").css(...).end()
Chain two finds on same parent$("ul").find(".a").css(...).end().find(".b").css(...)
Pop two stack levels.find(...).find(...).end().end()
Keep both parent and child sets.find("p").addBack() (not .end())
Without chaining (use variable)var $ul = $("ul"); $ul.find("li")...
After .filter() or .not()$("div").filter(".x").end()

📋 .end() vs .addBack() vs Variables

Three ways to work with earlier matched sets during a chain.

.end()
restore

Previous set only; current subset dropped

.addBack()
merge

Previous + current sets combined

Variable
var $x

Explicit reference without stack

Stack depth
-1 level

Each .end() pops one filter step

Examples Gallery

Examples 1–3 follow the official jQuery API documentation. Use DevTools or the Try-it links to run each snippet in the browser.

📚 Getting Started

Official jQuery demos for selection stack restoration.

Example 1 — Official Demo: Two .find() Calls with .end()

Style .foo red inside the first list, restore with .end(), then style .bar green — still scoped to the first list only.

jQuery
$( "ul.first" )
  .find( ".foo" )
  .css( "background-color", "red" )
  .end()
  .find( ".bar" )
  .css( "background-color", "green" );
Try It Yourself

How It Works

Without .end(), the second .find(".bar") would search inside the .foo elements — not the whole first list. .end() pops back to ul.first before the second find.

Example 2 — Official Demo: Border on Paragraphs, Not Spans

Find spans inside paragraphs, then .end() to restore the paragraph set and apply a red border — official Example 2.

jQuery
$( "p" )
  .find( "span" )
  .end()
  .css( "border", "2px red solid" );
Try It Yourself

How It Works

The intermediate .find("span") does not need styling here — it demonstrates navigating into a subset and returning. After .end(), .css() targets all matched p elements again.

📈 Practical Patterns

Stack visualization, comparison with .addBack(), and nested chains.

Example 3 — Official Demo: Visualize the Stack with Tag Names

Track which elements are in the jQuery object at each chain step — official Example 1 pattern with showTags.

jQuery
jQuery.fn.showTags = function ( n ) {
  var tags = this.map( function () { return this.tagName; } )
    .get().join( ", " );
  $( "b" ).eq( n ).text( tags );
  return this;
};

$( "p" )
  .showTags( 0 )           // P, P
  .find( "span" )
  .showTags( 1 )           // SPAN, SPAN, SPAN
  .css( "background", "yellow" )
  .end()
  .showTags( 2 )           // P, P again
  .css( "font-style", "italic" );
Try It Yourself

How It Works

The custom showTags plugin makes the invisible stack visible. After .find("span") the set contains spans; after .end() it is back to paragraphs.

Example 4 — .end() vs .addBack() After .find()

See how restore-only differs from merge — border on paragraphs only vs border on paragraphs and spans.

jQuery
// .end() — paragraphs only:
$( "#end-demo p" ).find( "span" ).end().css( "outline", "2px solid red" );

// .addBack() — paragraphs AND spans:
$( "#back-demo p" ).find( "span" ).addBack().css( "outline", "2px solid blue" );
Try It Yourself

How It Works

.end() drops the span subset entirely. .addBack() keeps both the span subset and the previous paragraph set in one collection.

Example 5 — Nested Filters with Two .end() Calls

Two narrowing steps require two pops to return to the original container.

jQuery
$( "#panel" )
  .find( "ul" )
  .find( "li" )
  .css( "color", "red" )
  .end()    // back to ul set
  .css( "border", "1px solid blue" )
  .end()    // back to #panel
  .css( "padding", "12px" );
Try It Yourself

How It Works

Each filtering method pushes onto the stack. The first .end() returns from li to ul; the second returns from ul to #panel — like closing two nested blocks.

🚀 Common Use Cases

  • Multi-step styling — style a subset, restore, style a different subset in the same container.
  • Avoid temp variables — keep long chains readable without var $parent = ....
  • After .find() / .filter() — return to the pre-filter matched set for the next operation.
  • Plugin development — narrow internally, then .end() to preserve caller chain context.
  • Visual symmetry — pair each narrowing method with a closing .end() for readable block structure.
  • Event binding chains — find interactive children, bind events, restore parent for delegation setup.

🧠 How .end() Pops the Selection Stack

1

Initial selection

Selector matches a set — pushed as stack base.

Stack: [A]
2

Filter narrows set

.find(), .filter(), etc. push new subset onto stack.

Stack: [A, B]
3

.end() pops

Current set B discarded; A becomes active again.

Stack: [A]
4

Continue chaining

Next method operates on restored set A.

📝 Notes

  • Available since jQuery 1.0; works in all jQuery 1.x, 2.x, and 3.x versions.
  • Takes no arguments — always pops exactly one stack level.
  • Does not modify the DOM — only changes the active jQuery collection.
  • Methods like .css() and .each() do not push onto the stack — only filtering/traversal methods that change the matched set do.
  • Calling .end() when the stack is empty returns an empty jQuery object.
  • For merging previous + current sets, use .addBack() instead of .end().

Browser Support

.end() has been part of jQuery since 1.0+. It is an internal stack operation with no browser-specific behavior.

jQuery 1.0+

jQuery .end()

Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. No native DOM equivalent — use variables or separate queries instead.

100% With jQuery loaded
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
.end() Universal

Bottom line: Safe in any jQuery project. Use .end() to restore previous sets during chaining; use .addBack() when you need both sets merged.

Conclusion

The jQuery .end() method restores the matched set from before the most recent filtering step by popping one level off the internal selection stack. It is essential for readable multi-step chains without temporary variables.

Remember the official two-list lesson: after styling .foo, .end() brings you back to ul.first so the next .find(".bar") searches the whole first list — not inside the red .foo items. When you need both parent and child, use .addBack() instead.

💡 Best Practices

✅ Do

  • Use .end() after .find() when the next step needs the parent set
  • Pair each narrowing step with .end() for readable nested chains
  • Prefer variables over deep stacks when chains exceed three levels
  • Use .addBack() when you need both previous and current elements
  • Visualize the stack when debugging unexpected selectors

❌ Don’t

  • Expect .end() to merge sets — that is .addBack()
  • Call .end() after methods that do not change the matched set
  • Build chains so long that stack depth becomes hard to track
  • Forget that without .end(), the next method targets the narrowed subset
  • Overuse .end() at the very end of a chain when the object is discarded anyway

Key Takeaways

Knowledge Unlocked

Five things to remember about .end()

Pop the stack, restore the previous set.

5
Core concepts
02

Restore

Previous set

Action
🔗 03

Chaining

No vars

Pattern
+ 04

addBack

Merge both

Compare
05

Nested

Multi end()

Depth

❓ Frequently Asked Questions

.end() ends the most recent filtering operation in the current chain and returns the matched set to its previous state. It pops one level off jQuery's internal selection stack — for example, after .find() narrows the set, .end() restores the elements from before that .find().
.end() replaces the current set with the previous set only — the narrowed subset is discarded from the jQuery object. .addBack() merges the previous set with the current set so both groups remain. Use .end() when you only need the earlier selection; use .addBack() when you need both.
Use .end() when chaining multiple filtering steps and you need to return to an earlier matched set without storing it in a variable — for example, styling .foo inside a list, then .end(), then styling .bar in the same original container.
No. .end() takes no parameters. It always pops exactly one level from the internal stack.
Yes. Each .end() pops one more level off the stack. A chain with two .find() calls can use two .end() calls to return to the original set — like closing nested blocks of code.
Usually no. Without chaining, you can save $('ul.first') in a variable and reuse it. .end() is most valuable when exploiting jQuery's method chaining to avoid extra variables.
Did you know?

jQuery’s documentation compares a long chain with .end() to structured code with nested blocks — each .find() opens a block and each .end() closes it. Some developers add a final .end() purely for visual symmetry even when the jQuery object is immediately discarded, though that extra call has a tiny performance cost.

Next: .pushStack() Method

Learn how plugins push custom sets onto the stack so .end() works.

.pushStack() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful