JavaScript | jQuery |选择图层:选择最贴心的孩子,但选择他们的孩子

时间:2015-11-09 02:32:48

标签: javascript jquery children closest

目标是选择任何后代 - ,不管直系后裔指示 - 而不是他们的孩子。换句话说,如果我正在document进行搜索,我想找到目标选择器所包含的所有的孩子

<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]);

理想情况下,这会选择#a1&amp;结果集中#b1。但是,不应包含#a2#a3#b2,因为这会将一个范围继续到多个

对此的补充函数将递归,以深入到集合中每个图层元素的下一个范围。因此,下一个递归调用将返回一个包含#a2#b2但不包含#a3[data-behavior]的任何子项(#b2)的集合。

另外,这个问题应该被标记为this question的副本,因为接受答案在这里可以接受 - 这里接受的答案应该是使用jQuery选择器或仅使用jQuery选择器证明它是不可能的。

修改

在@ guest271314的帮助下,我们得到了以下答案:

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

现在,可以使用递归函数获取父上下文并找到第一级范围 - 并以此方式无限期地重复。这是一个例子:

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);
        });
    }
},

请务必在到期时给予信任。

#prethanks

1 个答案:

答案 0 :(得分:1)

  

理想情况下,这会选择#a1&amp;结果集中的#b1

尝试将:not()用于第一个结果集,:first用于下一个结果

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>

  

因此,下一个递归调用将返回一个包含#a2#b2但不包含#a3[data-behavior]的任何子项(#b2)的集合。< / p>

使用$.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>