在不知道匹配元素的情况下,选择匹配元素,但不选择那些匹配元素的子元素。嵌套的职位

时间:2017-01-27 23:13:40

标签: javascript jquery html css

请建议更好的标题,以便让其他用户更容易找到此问题。

我尝试选择父元素的子元素,但子元素可能是子元素的子元素,对嵌套子元素的数量没有限制。我想选择那个孩子,但如果在很多嵌套孩子中有孩子的孩子,我不想让孩子被选中。例如:

<div class="section">
<div>  <!--First nested child (Take this and repeat as many times as you want within the parent 'section' class, structure of nested children changing each time.)-->
    <div>  <!--Second nested child (Can have potentially infinite sub-nests like first, second, etc.)-->
        <div class="block">  <!--Select this -->
        Select
            <div>
                <div class="block">  <!--DONT select this -->
                Don't select
                    <div class="section">
                        <div>  <!--More unknown nestings to an assumed infinite degree-->
                            <div class="block">  <!--Select this-->
                            Select
                                <div>
                                    <div class="block">Don't select</div>  <!--DONT select this -->
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div>
    <div>
        <div class="block">  <!--Select this -->
        Select
            <div>
                <div class="block">  <!--DONT select this -->
                Don't select
                    <div class="section">
                        <div>  <!--More unknown nestings to an assumed infinite degree-->
                            <div class="block">  <!--Select this-->
                            Select
                                <div>
                                    <div class="block">Don't select</div>  <!--DONT select this -->
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</div>

看起来非常可怕,但我们的想法是,我们只想在任何一个孩子中选择第一个出现,然后再不再出现。

我显然更喜欢使用CSS来进行此选择,但是如果需要,我们可以使用jQuery选择器。我不确定它是否可以在CSS中使用。

让你玩的小提琴:https://jsfiddle.net/78b3c6xh/1/

  

这个问题有三种解决方案。我选择了来自Arman P.的纯CSS作为答案,因为这是优先考虑的问题,它是最快最简单的解决方案。

     

第二个最好的是来自Susanne Peng,因为简单和最少使用jQuery。不确定效率,但它确实有效。

     

第三个是第一个解决问题的ibrahim mahrir,并使用依赖于jQuery的自定义javascript函数。

     

如果可能,建议在这种情况下使用CSS解决方案。解决问题的工作方法就是对答案的评论。

5 个答案:

答案 0 :(得分:2)

我认为只用CSS就不可能。

使用jQuery的解决方案:

$('.section').each(function() {
    $(this).find('.block').first().css('color', 'blue');
});

在这里小提琴:https://jsfiddle.net/78b3c6xh/2/

如果在.block下找到多个子.section,您可以采用以下方法:

$('.block').each(function() {
    var $closest = $(this).parent().closest('.section, .block');
    if ($closest.hasClass('section')) $(this).css('color', 'blue');
});

在这里小提琴:https://jsfiddle.net/78b3c6xh/5/

答案 1 :(得分:1)

这是有效的:

$(function(){
    // get the depth
    var count = $(".section").length;
    // array of matched elements
    var elements = [];

    // generate a selector for the '.section' that has a depth of 'depth'
    function getSelector(depth){
        var selector = "";
        for(var i = 0; i < depth; i++)
            selector += ".section ";
        return selector;
    }

    // for each depth select only the first '.block' level of that depth
    for(var i = 0; i < count; i++){
        // selector for the '.section' on this depth
        var selector = getSelector(i + 1);
        // select the '.block' of this depth that aren't children of other '.block' of this depth too.
        $(selector + ".block").not(selector + ".block .block").each(function(){
            // push all the matched element into the array
            elements.push(this);
        });
    }

    console.log(elements);
});

示例:

你的CSS错了,看看这个例子是否有效:

$(function() {
  // get the depth
  var count = $(".section").length;
  // array of matched elements
  var elements = [];

  // generate a selector for the '.section' that has a depth of 'depth'
  function getSelector(depth) {
    var selector = "";
    for (var i = 0; i < depth; i++)
      selector += ".section ";
    return selector;
  }

  // for each depth select only the first '.block' level of that depth
  for (var i = 0; i < count; i++) {
    // selector for the '.section' on this depth
    var selector = getSelector(i + 1);
    // select the '.block' of this depth that aren't children of other '.block' of this depth too.
    $(selector + ".block").not(selector + ".block .block").each(function() {
      // push all the matched element into the array
      $(this).addClass('selected');
    });
  }
});
.block {
  color: red;
}
.block.selected {
  color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="section">
  <div>
    <!--First nested child (Take this and repeat as many times as you want within the parent 'section' class, structure of nested children changing each time.)-->
    <div>
      <!--Second nested child (Can have potentially infinite sub-nests like first, second, etc.)-->
      <div class="block">
        <!--Select this -->
        Select
        <div>
          <div class="block">
            <!--DONT select this -->
            Don't select
            <div class="section">
              <div>
                <!--More unknown nestings to an assumed infinite degree-->
                <div class="block">
                  <!--Select this-->
                  Select
                  <div>
                    <div class="block">Don't select</div>
                    <!--DONT select this -->
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div>
    <div>
      <div class="block">
        <!--Select this -->
        Select
        <div>
          <div class="block">
            <!--DONT select this -->
            Don't select
            <div class="section">
              <div>
                <!--More unknown nestings to an assumed infinite degree-->
                <div class="block">
                  <!--Select this-->
                  Select
                  <div>
                    <div class="block">Don't select</div>
                    <!--DONT select this -->
                  </div>
                </div>
              </div>
              <div>
                <!--More unknown nestings to an assumed infinite degree-->
                <div class="block">
                  <!--Select this-->
                  Select
                  <div>
                    <div class="block">Don't select</div>
                    <!--DONT select this -->
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

答案 2 :(得分:0)

除非我遗漏了什么,为什么 example 无法工作?它会搜索与您的选择器查询匹配的第一个元素。 这实际上只是知道如何撰写适当的querySelector

另请注意,当您拥有节点引用时,您始终可以通过该引用访问后代节点。这就是DOM的本质。

&#13;
&#13;
document.querySelector("button").addEventListener("click", function(){
  var selector = document.getElementById("query").value;
  var node = document.querySelector(selector);
  var childNodes = node.querySelector("*");
  console.log("Found node: " + node);
  console.log("Node contents: " + node.innerHTML);

  node.setAttribute("class", "special");
  childNodes.setAttribute("class", "normal");

});
&#13;
code.q { font-weight:bold; color:#f00; }

.special { color:#0f0; }
.normal  { color:#000; }
&#13;
<div class="section">
<div>  <!--First nested child (Take this and repeat as many times as you want within the parent 'section' class, structure of nested children changing each time.)-->
    <div>  <!--Second nested child (Can have potentially infinite sub-nests like first, second, etc.)-->
        <div class="block">  Select this
            <div>
                <div class="block">  DONT select this
                    <div class="section">
                        <div>  <!--More unknown nestings to an assumed infinite degree-->
                            <div class="block">  Select this
                                <div>
                                    <div class="block"></div>  DONT select this
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</div>
<p>You can get whatever node you want, regardless of the DOM structure, you just have to know how to write your CSS selectors properly.</p>
<ul>
  <li>To get the first <code class="q">.block</code>, the selector would be: <code class="q">.block</code></li>
  <li>To get the third nested <code class="q">.block</code>, the selector would be: <code class="q">.block .block .block</code></li>
</ul>
<input type="text" id="query" value=".block">
<button>Search!</button>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

以下CSS选择按照当前提供的HTML工作,但不确定它是否可能在其他情况下失败,它有点取决于嵌套的外观。

.section .block{
  color: red;
}

.section > * > .block, .section > * > * > .block{
  color: blue;
}

https://jsfiddle.net/3owtetfb/1/

它也可能被反向选择&#34;如果嵌套不规则,我相信它会更准确地工作,请参阅: https://jsfiddle.net/xqf0u40r/

答案 4 :(得分:0)

据我所知,你需要这个css选择器: 见下面的工作示例

.section .block {
  color: red;
}

*:not(.block) > *:not(.block) > .block,
.section > .block {
  color: blue;
}
<div class="section">
<div>  <!--First nested child (Take this and repeat as many times as you want within the parent 'section' class, structure of nested children changing each time.)-->
    <div>  <!--Second nested child (Can have potentially infinite sub-nests like first, second, etc.)-->
        <div class="block">  <!--Select this -->
        Select
            <div>
                <div class="block">  <!--DONT select this -->
                Don't select
                    <div class="section">
                      <div class="block">  <!--Select this-->
                        Select
                        <div>
                          <div class="block">Don't select</div>  <!--DONT select this -->
                        </div>
                      </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div>
    <div>
        <div class="block">  <!--Select this -->
        Select
            <div>
                <div class="block">  <!--DONT select this -->
                Don't select
                    <div class="section">
                        <div>  <!--More unknown nestings to an assumed infinite degree-->
                          <div>
                            <div class="block">  <!--Select this-->
                            Select
                                <div>
                                    <div class="block">Don't select</div>  <!--DONT select this -->
                                </div>
                            </div>
                          </div>
                        </div>
                        <div>  <!--More unknown nestings to an assumed infinite degree-->
                          <div>
                            <div class="block">  <!--Select this-->
                            Select
                                <div>
                                    <div class="block">Don't select</div>  <!--DONT select this -->
                                </div>
                            </div>
                          </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</div>