简体   繁体   中英

JavaScript | jQuery | Selecting In Layers: Select Closest Children But Their Children

The goal is to select any descendant(s) -- regardless of direct-descendant indication -- but not their children. In other words, if I'm searching from document I'd like to find all children which are not wrapped by the target selector :

<div id="a1" class="scenario-1" data-behavior="test">
    test
    <div id="a2" data-behavior="test">
        test 1
        <div id="a3" data-behavior="test">
            test 2
        </div>
    </div>
</div>

<div class="scenario-2">
    <div id="b1" data-behavior="test">
        test 1
        <div id="b2" data-behavior="test">
            test 2
        </div>
    </div>
</div>

$(document).findAllInFirstLayer([data-behavior]);

This, ideally, would select #a1 & #b1 in the result-set. However, #a2 , #a3 , and #b2 should not be included, as this would proceed one scope to many .

The complimentary function for this will be recursive to drill down to the next scope for each layer-element in the set. So the next recursive call would return a set containing #a2 , #b2 , but not #a3 or any children ( [data-behavior] ) of #b2 .

Also, this Question should not be marked as a duplicate of this question as the Accepted-Answer is not acceptable here -- the accepted answer here should use a jQuery selector or prove its impossibility with only using a jQuery selector.

Edit

With @guest271314's help, we reached the following answer:

'[data-behavior]:not([data-behavior] [data-behavior]), [data-behavior]:first'

Now, a recursive function can be used to take a parent-context and find the first-level scopes -- and recur in that fashion indefinitely. Here's an example:

arm: function autoRegisterModules(parent) {
    var $firstScope = $(parent).find('[data-behavior]:not([data-behavior] [data-behavior]), [data-behavior]:first');
    console.log('#context, #first-scope', parent, $firstScope);
    if ($firstScope.length) {
        $firstScope.each(function (i, p) {
            autoRegisterModules(p);
        });
    }
},

Please be sure to give credit where it's due.

#prethanks

This, ideally, would select #a1 & #b1 in the result-set.

Try using :not() for first result set , :first for next results

 var first = $("[data-behavior]:not([data-behavior] [data-behavior])"), second = first.find("[data-behavior]:first"), third = second.find("[data-behavior]:first"); console.log(first, second, third); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script> <div id="a1" class="scenario-1" data-behavior="test"> test <div id="a2" data-behavior="test"> test 1 <div id="a3" data-behavior="test"> test 2 </div> </div> </div> <div class="scenario-2"> <div id="b1" data-behavior="test"> test 1 <div id="b2" data-behavior="test"> test 2 </div> </div> </div> 


So the next recursive call would return a set containing #a2 , #b2 , but not #a3 or any children ( [data-behavior] ) of #b2 .

using $.fn.extend()

 (function($) { $.fn.extend({ layers: function(sel) { var root, next, res = [], sel = sel || this.selector; if ($(sel + ":not(" + sel + " " + sel + ")").length) { root = $(sel + ":not(" + sel + " " + sel + ")"); res.push([root]); if (root.find(sel + ":first").length) { next = root.find(sel + ":first"); res.push([next]); while (next.find(sel + ":first").length) { next = next.find(sel + ":first"); res.push([next]) } } } return this.data("layers", res) } }) }(jQuery)) var layers = $("[data-behavior]").layers().data("layers"); $.each(layers, function(key, value) { console.log(key, value[0]) }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script> <div id="a1" class="scenario-1" data-behavior="test"> test <div id="a2" data-behavior="test"> test 1 <div id="a3" data-behavior="test"> test 2 </div> </div> </div> <div class="scenario-2"> <div id="b1" data-behavior="test"> test 1 <div id="b2" data-behavior="test"> test 2 </div> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM