我根据解决方案按类对<li>元素进行分组,但需要帮助了解其工作原理</li>

时间:2015-03-16 16:35:32

标签: javascript jquery

想象一下无序列表:

<ul id="something">
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <li class="child">child</li>
  <li class="child">child</li>
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <li class="child">child</li>
  <li class="child">child</li>
</ul>

我想把上面的例子变成:

<ul id="something">
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <ul>
    <li class="child">child</li>
    <li class="child">child</li>
  </ul>
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <ul>
    <li class="child">child</li>
    <li class="child">child</li>
  </ul>
</ul>

我已根据此处找到的解决方案成功完成此操作:https://stackoverflow.com/a/9023265/1447679

$('#Something').children('li.child:not(li.child + li.child)').each(function() {
  $(this).nextUntil('li.parent').andSelf().wrapAll('<ul />');
});

如果我不使用:not(选择器+选择器),则会导致奇怪的连续嵌入ul&gt; li> ul&gt;李等。

所以基本上我只想清楚地理解它。

3 个答案:

答案 0 :(得分:1)

<强>工作

看起来代码逐步描述了它的作用。

它选择第一个子节点,并为每个子节点收集它的所有兄弟节点,直到下一个父节点,包括它自己,并将该集合包装到ul

或:

<强>带注释

$('li.child:not(li.child + li.child)')选择每个第一个孩子(不在另一个孩子之前的孩子)。

对于每个(.each(function() {),收集其所有兄弟姐妹,直到下一个父(nextUntil('li.parent')),包括它自己(andSelf),并将该集合包装成{{1 (ul)。

不(孩子+孩子)和nextUntil

所以魔术是wrapAll('<ul>')(选择每个&#39;组&#39;的第一个孩子)和not(li.child + li.child)方法(选择所有后续孩子,直到下一个父母)。

如果删除nextUntil,您将获得所有孩子及其后来的兄弟姐妹,导致重叠的群体全部被包裹。这严重扰乱了你的HTML。

其他相关差异

the other thread中您的版本与Dan A的版本之间存在一些细微差别:

首先,那个只使用一个类,因为他使用not(..+..)作为选择器,所以基本上所有不是孩子的东西都被视为父。

其次,他将其包含在not(li.child)而不是<li><ul>中。这是有道理的,因为项目已经在列表中。子集合需要包装在<ul>中以保持父列表有效。 li以外的元素无效为li元素的直接子元素。您的代码会将ul置于父ul内,从技术上讲,HTML会无效。浏览器可能会为您解决此问题,方法是添加隐含的ul

答案 1 :(得分:0)

基本上:not(li.child + li.child) seletor的作用是选择一组直接连续的li.child元素中第一个出现的li.child元素。

如果我们剖析标记,我们可以看到哪个li.child满足选择器:

<ul id="something">
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <li class="child">child</li>    <!-- satisfies, not immediate sibling of li.child -->
  <li class="child">child</li>    <!-- fails, because is immediate sibling of li.child -->
  <li class="parent">parent</li>
  <!-- and etc -->
</ul>

以更直接的方式查看它:

<ul id="something">
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <li class="child">child</li>    <!-- is not li.child+li.child -->
  <li class="child">child</li>    <!-- is     li.child+li.child -->
  <li class="parent">parent</li>
  <li class="parent">parent</li>
  <li class="child">child</li>    <!-- is not li.child+li.child -->
  <li class="child">child</li>    <!-- is     li.child+li.child -->
</ul>

答案 2 :(得分:0)

正在发生的事情是你选择了具有.child级别的li元素,而以前的兄弟姐妹没有.child类。

说明:

li.child + li.child选择具有child类的li元素,该元素直接位于具有child类的li元素之后

:not()排除了你在()内投掷的任何内容。