2017-11-10 108 views
1

为什么我不能在jQuery中选择一个孩子的孩子?我想使用.children()方法和>选择器向课程的孩子添加课程。请参见下面的代码:选择一个孩子的子女

$(function(){ 
     // main expansion element 
     $(".expander").click(function() { 
      var subShown = $(this).children("ul > li").hasClass("show"); 
      if (!subShown) { 
       $(this).children(".indented").slideDown('100').addClass("show"); 
       $(this).children(".caret").addClass("reversedCaret"); 
      } else { 
       $(this).children(".indented").slideUp('100').removeClass("show"); 
       $(this).children(".caret").removeClass("reversedCaret"); 
      } 
     }); 
    }); 

HTML:

<div class="expander"> 
        <span class="caret downCaret right visibleCaret">+</span> 
        <ul> 
        <li class="category">Item 1<a href="http://www.google.com"></a></li> 
        <li class="indented"><a href="http://www.google.com">Item 2</a></li> 
        <li class="indented"><a href="http://www.google.com">Item 3</a></li> 
        </ul> 
       </div> 

当我点击expander它不会将该类添加到我的li元素。为什么?

+2

的'li'是在膨胀,这就是'儿童不直接孩子() '回报。你需要使用'find()'而不是'children()'。 'children()'和find('> *')基本相同' – Taplar

+0

我试过'.find()'但我无法正常工作。会在'.children()'之前还是之后? – kawnah

+2

看看斯科特的解决方案。你根本不用 - 要 - 完全使用孩子()。 – Taplar

回答

2

JQuery documentation.children()

的。儿童()方法从.find()在不同。儿童()只 行进的单一电平向下DOM树而.find( )可以遍历 多层次选择后代元素(孙, 等)以及。

你真的甚至不需要使用.children()这一点。简单得多的解决方案是通过在选择器之后向JQuery传递第二个参数,仅使用provide context for your queries

$(function(){ 
 
     // main expansion element 
 
     $(".expander").click(function() { 
 
     
 
      // Just for demonstration: ************************************************* 
 
      
 
      // 2 because of <span> and <ul> 
 
      console.log($(this).children().length);   
 
      
 
      // 0 because anything beyond children isn't returned in the first place 
 
      console.log($(this).children("ul > li").length); 
 
      // ************************************************************************* 
 
     
 
      // By passing "this" as the second argument to JQuery, after the selector, 
 
      // it sets the context for the search to only "this", so the entire DOM 
 
      // is not searched, just the object that "this" is bound to. 
 
      var subShown = $("ul > li", this).hasClass("show"); 
 
      if (!subShown) { 
 
       $(".indented", this).slideDown('100').addClass("show"); 
 
       $(".caret", this).addClass("reversedCaret"); 
 
      } else { 
 
       $(".indented", this).slideUp('100').removeClass("show"); 
 
       $(".caret", this).removeClass("reversedCaret"); 
 
      } 
 
     }); 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="expander"> 
 
    <span class="caret downCaret right visibleCaret">+</span> 
 
    <ul> 
 
    <li class="category">Item 1<a href="http://www.google.com"></a></li> 
 
    <li class="indented"><a href="http://www.google.com">Item 2</a></li> 
 
    <li class="indented"><a href="http://www.google.com">Item 3</a></li> 
 
    </ul> 
 
</div>

+0

谢谢你 - 但我仍然很难理解为什么我的版本不起作用?所以如果'.children()'在dom树中下了一层,我的li就是div的两层。所以考虑到这一点,不应该使用'.children()'和'>'选择器给我什么我想要的? – kawnah

+0

@kawnah'.children()'方法返回一组包**仅**子元素。因此,即使你的选择器说要从那里搜索更深,搜索将发生的元素集也就没有任何元素在较低的深度。 –

+1

@kawnah我已经更新了答案,以包含一些示例,这些示例显示调用'.children()'只会返回直接子节点,除此之外没有其他任何内容。所以试图深入搜索没有任何回报。 –

0

如果您仍想接近它,你的(而不是给出答案呢,这是更好的方式),然后改变这个

$(this).children("ul > li") 

对此:

$(this).children('ul').children() 

选择的孩子就是这样。

+0

好的..我正在与斯科特马库斯的回答,但谢谢你 – kawnah

0

可以使用.find('>ul>li'),例如:

var expander = $(".expander") 

expander.on('click', function(){ 
    var li = expender.find('>ul>li') 
    li.hasClass("show") 
}) 
0

.querySelector

document.querySelector("section > div").classList.add("my-gray");
.my-gray{ 
 
    background: gray; 
 
}
<section> 
 
Foo 
 
<div> 
 
Bar 
 
</div> 
 
</section>