Most of jQuery's DOM traversal methods operate on a jQuery object instance and produce a new one, matching a different set of DOM elements. When this happens, it is as if the new set of elements is pushed onto a stack that is maintained inside the object. Each successive filtering method pushes a new element set onto the stack. If we need an older element set, we can use end()
to pop the sets back off of the stack.
Suppose we have a couple short lists on a page:
<ul class="first"> <li class="foo">list item 1</li> <li>list item 2</li> <li class="bar">list item 3</li> </ul> <ul class="second"> <li class="foo">list item 1</li> <li>list item 2</li> <li class="bar">list item 3</li> </ul>
The end()
method is useful primarily when exploiting jQuery's chaining properties. When not using chaining, we can usually just call up a previous object by variable name, so we don't need to manipulate the stack. With end()
, though, we can string all the method calls together:
$( "ul.first" ) .find( ".foo" ) .css( "background-color", "red" ) .end() .find( ".bar" ) .css( "background-color", "green" );
This chain searches for items with the class foo
within the first list only and turns their backgrounds red. Then end()
returns the object to its state before the call to find()
, so the second find()
looks for '.bar' inside <ul class="first">
, not just inside that list's <li class="foo">
, and turns the matching elements' backgrounds green. The net result is that items 1 and 3 of the first list have a colored background, and none of the items from the second list do.
A long jQuery chain can be visualized as a structured code block, with filtering methods providing the openings of nested blocks and end()
methods closing them:
$( "ul.first" ) .find( ".foo" ) .css( "background-color", "red" ) .end() .find( ".bar" ) .css( "background-color", "green" ) .end();
The last end()
is unnecessary, as we are discarding the jQuery object immediately thereafter. However, when the code is written in this form, the end()
provides visual symmetry and a sense of completion âmaking the program, at least to the eyes of some developers, more readable, at the cost of a slight hit to performance as it is an additional function call.
Selects all paragraphs, finds span elements inside these, and reverts the selection back to the paragraphs.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>end demo</title> <style> p, div { margin: 1px; padding: 1px; font-weight: bold; font-size: 16px; } div { color: blue; } b { color: red; } </style> <script src="https://code.jquery.com/jquery-1.10.2.js"></script> </head> <body> <p> Hi there <span>how</span> are you <span>doing</span>? </p> <p> This <span>span</span> is one of several <span>spans</span> in this <span>sentence</span>. </p> <div> Tags in jQuery object initially: <b></b> </div> <div> Tags in jQuery object after find: <b></b> </div> <div> Tags in jQuery object after end: <b></b> </div> <script> 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 ) .find( "span" ) .showTags( 1 ) .css( "background", "yellow" ) .end() .showTags( 2 ) .css( "font-style", "italic" ); </script> </body> </html>
Selects all paragraphs, finds span elements inside these, and reverts the selection back to the paragraphs.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>end demo</title> <style> p { margin: 10px; padding: 10px; } </style> <script src="https://code.jquery.com/jquery-1.10.2.js"></script> </head> <body> <p><span>Hello</span>, how are you?</p> <script> $( "p" ) .find( "span" ) .end() .css( "border", "2px red solid" ); </script> </body> </html>
Please login to continue.