Mikko Ohtamaa Mikko Ohtamaa - 1 year ago 89
jQuery Question

jQuery: find() children until a certain threshold element is encountered

I have a nested table structure like


<td id="first">

<div class="wrapper">
<input name=1>

<input name=2>


<td id="second">

<input name=3>

I have jQuery selection
. I'd like to traverse and
all children
within this
context, but not to descent into the nested

So I need a jQuery trick which

  • Will
    all children elements of a certain element

  • Will descent n levels down in DOM tree

  • But will stop descending if certain a element (
    ) is encountered, so that the selector doesn't select inputs of a nested tables (which will be handled separately)

  • There could be any number of nested
    levels, so the solution should work no matter how many parent
    or children
    are encountered within the scope of $("#first")
    or any other

I checked other jQuery find until questions. They have answers, but seems like they do not fill the last criteria

Answer Source

I had a similar issue in this other question. I ended up finally figuring out a plugin on my own after going back and forth with some people trying to think of a find selector.

USAGE : ExclusiveInputs = $('#first').findExclude('input','table');

// Find-like method which masks any descendant
// branches matching the Mask argument.
$.fn.findExclude = function( Selector, Mask, result){

    // Default result to an empty jQuery object if not provided
    var result = typeof result !== 'undefined' ?
                result :
                new jQuery();

    // Iterate through all children, except those match Mask

        var thisObject = jQuery( this );
        if( thisObject.is( Selector ) ) 
            result.push( this );

        // Recursively seek children without Mask
        if( !thisObject.is( Mask ) )
            thisObject.findExclude( Selector, Mask, result );

    return result;

(Condensed Version):

$.fn.findExclude = function( selector, mask, result )
    var result = typeof result !== 'undefined' ? result : new jQuery();
    this.children().each( function(){
        var thisObject = jQuery( this );
        if( thisObject.is( selector ) ) 
            result.push( this );
        if( !thisObject.is( mask ) )
            thisObject.findExclude( selector, mask, result );
    return result;