jQuery API

.nextUntil()

.nextUntil( [ selector ] ) Returns: jQuery

Description: Get all following siblings of each element up to but not including the element matched by the selector.

  • version added: 1.4.nextUntil( [ selector ] )

    selectorA string containing a selector expression to indicate where to stop matching following sibling elements.

Given a jQuery object that represents a set of DOM elements, the .nextUntil() method allows us to search through the successors of these elements in the DOM tree, stopping when it reaches an element matched by the method's argument. The new jQuery object that is returned contains all following siblings up to but not including the one matched by the .nextUntil() selector.

If the selector is not matched or is not supplied, all following siblings will be selected; in these cases it selects the same elements as the .nextAll() method does when no filter selector is provided.

Consider a page with a simple definition list as follows:

<dl>
  <dt>term 1</dt>
  <dd>definition 1-a</dd>
  <dd>definition 1-b</dd>
  <dd>definition 1-c</dd>
  <dd>definition 1-d</dd>

  <dt id="term-2">term 2</dt>
  <dd>definition 2-a</dd>
  <dd>definition 2-b</dd>
  <dd>definition 2-c</dd>

  <dt>term 3</dt>
  <dd>definition 3-a</dd>
  <dd>definition 3-b</dd>
</dl>

If we begin at the second term, we can find the elements which come after it until a following <dt>.

$('#term-2').nextUntil('dt').css('background-color', 'red');

The result of this call is a red background behind definitions 2-a, 2-b, and 2-c.

Example:

Find the siblings that follow <dt id="term-2"> up to the next <dt> and give them a red background color.

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
	<dl>
  <dt>term 1</dt>
  <dd>definition 1-a</dd>
  <dd>definition 1-b</dd>
  <dd>definition 1-c</dd>
  <dd>definition 1-d</dd>

  <dt id="term-2">term 2</dt>
  <dd>definition 2-a</dd>
  <dd>definition 2-b</dd>
  <dd>definition 2-c</dd>

  <dt>term 3</dt>
  <dd>definition 3-a</dd>
  <dd>definition 3-b</dd>
</dl>
<script>
    $("#term-2").nextUntil("dt")
      .css("background-color", "red")
</script>
</body>
</html>

Demo:

Comments

  • Support requests, bug reports, and off-topic comments will be deleted without warning.

  • Please do post corrections or additional examples for .nextUntil() below. We aim to quickly move corrections into the documentation.
  • If you need help, post at the forums or in the #jquery IRC channel.
  • Report bugs on the bug tracker or the jQuery Forum.
  • Discussions about the API specifically should be addressed in the Developing jQuery Core forum.
  • The nextUntil (and I guess prevUntil and parentsUntil) also allow you to pass in a second argument that filters the results. for example, $('p').nextUntil('#blah','div') will only return div sibling elements up to the #blah element.

    I can't for the life of me find out how that's working in the source, but it is ;)
  • Yeah, I noticed this the other day, too. Thanks for noting it here. I'll try to update the docs as soon as I can.

    The filtering takes place in lines 213-215 of traversing.js (or 3957-3959 of jquery.js):

    if ( selector && typeof selector === "string" ) {
    ret = jQuery.filter( selector, ret );
    }
  • gilbeRt_fox
    How can I make a function as in .each() ? Is this posible?
    I mean, i.e.:

    $("tr").nextUntil(function(index, domElement){
    // CODE HERE
    });
  • Bob
    Forgot to add that I was using Firefox 3.5.3 on Ubuntu 8.04 with Firebug. I can't say how the results will turn out in other browsers, but there will probably be a similarly dramatic difference.
  • Bob
    I did some basic benchmarking of nextUntil() to test the speed. Here, the javascript is traversing a table of this format:

    <table>
    <tbody>
    <tr id='jqueryfirstrow1'><td>Text</td><td>
    Text
    </td><td>Text</td></tr>
    <tr><td>Text</td><td>
    Text
    </td><td>Text</td></tr>
    ... snip tr 1120 times ...
    <tr id='jquerylastrow1' ><td>Text</td><td>
    Text
    </td><td>Text</td></tr>
    ... snip 5 more tr ...
    </tbody>
    </table>

    Here is the javascript:

    var firstRow = jQuery('#jqueryfirstrow1');
    var time = new Date();
    var row = firstRow.next();
    var rowArray = [];
    while (row.length && !row.is('#jquerylastrow1')) {
    rowArray.push(row[0]);
    row = row.next();
    }
    console.log('Total time with next: ' + ((new Date()) - time));

    rowArray = [];
    var time = new Date();
    var row = firstRow;
    var rowArray = row.nextUntil('#jquerylastrow1');
    console.log('Total time with nextUntil: ' + ((new Date()) - time));

    var time = new Date();
    var row = document.getElementById('jqueryfirstrow1').nextSibling;
    var rowArray = [];
    while (!!row && (row.id != 'jquerylastrow1')) {
    rowArray.push(row);
    row = row.nextSibling;
    }
    console.log('Total time with nextSibling: ' + ((new Date()) - time));

    Basically, in the end you should always end up with the same rows in the array. Performing the above ten times in a row and averaging the results, I get this:

    Average time with next: 236
    Average time with nextUntil: 164
    Average time with nextSibling: 11

    As the results show, just going with plain javascript is a massive performance improvement over using jQuery to retrieve the rows, at least when you use id's to identify the table rows between which your result set will be.

    Also, nextUntil is a significant improvement over putting something together using only next, and of course has the versatility of using any jQuery selector.

    Additionally, you can use jQuery on the rowArray generated using plain javascript to use the jQuery functions in the examples above on those rows. I tried this and it was on average 200ms faster when the rows are first retrieved using plain javascript.

    It won't make that much of a difference when you only have three elements as in the examples above, but it certainly is something to keep in mind when you're handling large amounts of elements and performance is critical.
  • FYI, If you're interested in how this method came to be, check out
    jQuery Untils: nextUntil, prevUntil, parentsUntil