想象一个无序列表:
<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(selector + 选择器),它会导致奇怪的连续嵌入 ul > li > ul > li 等。
所以基本上我只是想清楚地理解它。
最佳答案
工作
看起来代码一步步描述了它的作用。
它选择第一个子级,对于每个子级,收集其所有兄弟级,直到下一个父级(包括其自身),并将该集合包装到 ul
中。 .
或者:
带注释
$('li.child:not(li.child + li.child)')
选择每个第一个子项(前面没有其他子项的子项)。
对于其中的每一个 ( .each(function() {
),收集其所有 sibling ,直到下一个父级 ( nextUntil('li.parent')
),包括其自身 ( andSelf
),并将该集合包装到 ul
中。 (wrapAll('<ul>')
)。
not(child+child) 和 nextUntil
所以神奇之处在于 not(li.child + li.child)
的组合(选择每个“组”的第一个子项),以及 nextUntil
方法(选择所有后续子级,直到下一个父级)。
如果删除 not(..+..)
,您将获得所有 child 及其后续 sibling ,从而导致重叠的组全部被包裹。这会严重扰乱你的 HTML。
其他相关差异
您的版本与 the other thread 中 Dan A 的版本之间存在一些细微差别。 :
首先,那个人只适用于一个类,因为他使用 not(li.child)
作为选择器,所以基本上所有不是子元素的东西都被视为父元素。
其次,他将其包裹在 <li><ul>
中。而不仅仅是<ul>
。这是有道理的,因为这些项目已经在列表中了。 children 的集合需要用 li
包裹起来。以保持父列表有效。 li
以外的元素作为 ul
的直接子代无效元素。您的代码将放置 ul
在父级内部 ul
,从技术上讲,使 HTML 无效。不过,浏览器可能会通过添加隐含的 li
来为您解决此问题。 .
关于javascript - 我根据解决方案按类对 <li> 元素进行分组,但需要帮助理解它的工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29082179/