Konrad Viltersten
Konrad Viltersten

Reputation: 39118

Selector in jQuery working in an unintuitive way

I have a selector as follows.

subMenus.children("li.tab").children("a").each(function () { ... }

It works as supposed to. Then, I read on the website that the following is also supposed to work (and since it's more compact, I prefer it that way).

subMenus.children("li.tab>a").each(function () { ... }

However, the latter seems not to find any elements as the action in the squiglies doesn't execute. What am I missing?

Edit

Markup as requested.

<ul id="submenu1" class="tabs tabs-transparent">
  <li class="tab"><a href="#">A</a></li>
  <li class="tab"><a href="#">B</a></li>
</ul>
<ul id="submenu2" class="tabs tabs-transparent">
  <li class="tab"><a href="#">A</a></li>
  <li class="tab"><a href="#">B</a></li>
</ul>
<ul id="submenu3" class="tabs tabs-transparent">
  <li class="tab"><a href="#">A</a></li>
  <li class="tab"><a href="#">B</a></li>
</ul>

Upvotes: 0

Views: 48

Answers (4)

Alex.S
Alex.S

Reputation: 355

.children() would only select direct children. So subMenus.children("li.tab>a") would select anchor tags that are direct children of subMenus, and also direct children of li.tab.

Here you can use .find() instead: subMenus.find(">li.tab>a").each()

Upvotes: 1

Daerik
Daerik

Reputation: 4277

A child combinator in CSS is the "greater than" symbol, it looks like this:

ol > li {
  color: red;
}

It means "select elements that are direct descendants only". In this case: "select list items that are direct descendants of an ordered list". To illustrate:

<ol>
  <li>WILL be selected</li>
  <li>WILL be selected</li>
  <ul>
     <li>Will NOT be selected</li>
     <li>Will NOT be selected</li>
  </ul>
  <li>WILL be selected</li>
</ol>

Try removing the > symbol.

$("li.tab a");

The first jQuery selector is looking for children of your <li/> (including grandchildren).

$("li.tab").children("a");

Whereas your second jQuery selector is looking for direct children of your <li/> (NOT including grandchildren).

$("li.tab > a");

Update: You'll want to use .find instead of .children because

The .children() method differs from .find() in that .children() only travels a single level down the DOM tree while .find() can traverse down multiple levels to select descendant elements (grandchildren, etc.) as well.

Source: https://api.jquery.com/children/

Upvotes: 3

JonSG
JonSG

Reputation: 13087

Try find().

Technically "li.tab > a" is not a "child" of subMenus

$(".tabs").find("li.tab>a").each(function () { console.log(this); });
<ul id="submenu1" class="tabs tabs-transparent">
  <li class="tab"><a href="#">A</a></li>
  <li class="tab"><a href="#">B</a></li>
</ul>
<ul id="submenu2" class="tabs tabs-transparent">
  <li class="tab"><a href="#">A</a></li>
  <li class="tab"><a href="#">B</a></li>
</ul>
<ul id="submenu3" class="tabs tabs-transparent">
  <li class="tab"><a href="#">A</a></li>
  <li class="tab"><a href="#">B</a></li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 1

Dan Kaufman
Dan Kaufman

Reputation: 115

Try this

subMenus.children("li.tab>a").each(function () { ... }

Upvotes: 0

Related Questions