如何递归循环一个ul并找出其中有多少个ul
How to loop through a ul recursively and find out how many ul's it has in it
我正在尝试在 jquery 中编写一个函数,该函数将循环遍历其中嵌套了 ul 的 ul。我希望它跟踪我有多少 ul 或 "layers",并给对应于 [=26= 的 ul 的 li children 赋予一个 class 标签] 他们的 parent ul 已打开。
html的结构是这样的`
<div class="region region--megamenu">
<div class="block block--services-menu">
<ul class="menu">
<li class="first last expanded active-trail">
<a href="/services" class="active-trail">Services</a>
<ul class="menu"> <!-- This ul can have any number of metacategory li's inside of it -->
<li class="second layer of li">
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
<li>
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
每个 li 都会得到一个数字作为新的 class 标签。
因此第一个 li 元素将获得标签 <li class="1 first layer of li">
,第二层 li 将被标记为 <li class="2 second layer of li">
您可以使用 JQuery .find()
方法轻松完成此操作。
HTML
<div class="region region--megamenu">
<div class="block block--services-menu">
<ul class="menu">
<li class="first last expanded active-trail">
<a href="/services" class="active-trail">Services</a>
<ul class="menu"> <!-- This ul can have any number of metacategory li's inside of it -->
<li class="second layer of li">
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
<li>
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="info"></div>
JS/JQUERY
var allListElements = $( "ul" );
var ulsInUl = $( "ul.menu" ).find( allListElements ).length;
document.getElementById("info").innerHTML = "Uls in UL Class main: " + ulsInUl;
看看这个 JSFiddle:http://jsfiddle.net/aaaprbst/1/
在纯 JS 中,您可以使用递归函数(尽管线性函数会更快)。这会降低 DOM 并向每个 LI 添加 class。当在 LI 上递归调用时,它会增加该调用的层数。
不确定是否符合您的目的,但可能足够接近。您还可以获取 UL,然后将特定于层的 class 添加到其直接 LI 子级。
如果需要,可以优化以下函数以跳过没有 LI 子元素的非空元素(例如脚本元素)。
<style type="text/css">
.foo-0 {
background-color: red;
}
.foo-1 {
background-color: blue;
}
.foo-2 {
background-color: green;
}
</style>
<div id="d0">
<ul>
<li>layer 1
<li>layer 1
<ul>
<li>layer 2
<li>layer 2
<ul>
<li>layer 3
<li>layer 3
</ul>
<li>layer 2
</ul>
<li>layer 1
<li>layer 1
</ul>
</div>
<script>
/*
** @param {DOM element} root - element to start from, default is document.body
** @param {string} classPre - prefix for class to add
** @param {number} layer - current level, default is 0
*/
function addULLayerClass(root, classPre, layer) {
root = root || document.body;
layer = layer || 0;
var node, nodes = root.childNodes;
var tagName;
for (var i=0, iLen=nodes.length; i<iLen; i++) {
node = nodes[i];
tagName = node.tagName && node.tagName.toLowerCase();
// If this is an LI, add class with layer number
// and call recursively
if (tagName == 'li') {
node.className = classPre + '-' + layer;
addULLayerClass(node, classPre, layer + 1);
// Otherwise, if it's an element that can have children,
// call recursively
} else if (node.nodeType == 1) {
addULLayerClass(node, classPre, layer);
}
}
}
addULLayerClass(document.getElementById('d0'), 'foo');
</script>
这是我实现的代码,它完全符合我的要求。感谢大家的贡献。
var parentUL = $( "ul.menu" );
var startSearchForParentsHere = ".block--services-menu";
$( startSearchForParentsHere ).find( parentUL ).each(function(){
layersDeep = $(this).parentsUntil(startSearchForParentsHere, parentUL).length;
$(this).children().addClass('accordion-layer' + ' ' + layersDeep);
})
也非常感谢进一步的反馈和其他创造性的解决方案!
我正在尝试在 jquery 中编写一个函数,该函数将循环遍历其中嵌套了 ul 的 ul。我希望它跟踪我有多少 ul 或 "layers",并给对应于 [=26= 的 ul 的 li children 赋予一个 class 标签] 他们的 parent ul 已打开。 html的结构是这样的`
<div class="region region--megamenu">
<div class="block block--services-menu">
<ul class="menu">
<li class="first last expanded active-trail">
<a href="/services" class="active-trail">Services</a>
<ul class="menu"> <!-- This ul can have any number of metacategory li's inside of it -->
<li class="second layer of li">
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
<li>
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
每个 li 都会得到一个数字作为新的 class 标签。
因此第一个 li 元素将获得标签 <li class="1 first layer of li">
,第二层 li 将被标记为 <li class="2 second layer of li">
您可以使用 JQuery .find()
方法轻松完成此操作。
HTML
<div class="region region--megamenu">
<div class="block block--services-menu">
<ul class="menu">
<li class="first last expanded active-trail">
<a href="/services" class="active-trail">Services</a>
<ul class="menu"> <!-- This ul can have any number of metacategory li's inside of it -->
<li class="second layer of li">
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
<li>
<a href="/metacategory-page">Metacategory Pages</a>
<ul class="menu"> <!-- This ul can have any number of ul's inside of it -->
<li>
<a href="/service-page-url"></a>
</li>
<li>
<a href="/service-page-url"></a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="info"></div>
JS/JQUERY
var allListElements = $( "ul" );
var ulsInUl = $( "ul.menu" ).find( allListElements ).length;
document.getElementById("info").innerHTML = "Uls in UL Class main: " + ulsInUl;
看看这个 JSFiddle:http://jsfiddle.net/aaaprbst/1/
在纯 JS 中,您可以使用递归函数(尽管线性函数会更快)。这会降低 DOM 并向每个 LI 添加 class。当在 LI 上递归调用时,它会增加该调用的层数。
不确定是否符合您的目的,但可能足够接近。您还可以获取 UL,然后将特定于层的 class 添加到其直接 LI 子级。
如果需要,可以优化以下函数以跳过没有 LI 子元素的非空元素(例如脚本元素)。
<style type="text/css">
.foo-0 {
background-color: red;
}
.foo-1 {
background-color: blue;
}
.foo-2 {
background-color: green;
}
</style>
<div id="d0">
<ul>
<li>layer 1
<li>layer 1
<ul>
<li>layer 2
<li>layer 2
<ul>
<li>layer 3
<li>layer 3
</ul>
<li>layer 2
</ul>
<li>layer 1
<li>layer 1
</ul>
</div>
<script>
/*
** @param {DOM element} root - element to start from, default is document.body
** @param {string} classPre - prefix for class to add
** @param {number} layer - current level, default is 0
*/
function addULLayerClass(root, classPre, layer) {
root = root || document.body;
layer = layer || 0;
var node, nodes = root.childNodes;
var tagName;
for (var i=0, iLen=nodes.length; i<iLen; i++) {
node = nodes[i];
tagName = node.tagName && node.tagName.toLowerCase();
// If this is an LI, add class with layer number
// and call recursively
if (tagName == 'li') {
node.className = classPre + '-' + layer;
addULLayerClass(node, classPre, layer + 1);
// Otherwise, if it's an element that can have children,
// call recursively
} else if (node.nodeType == 1) {
addULLayerClass(node, classPre, layer);
}
}
}
addULLayerClass(document.getElementById('d0'), 'foo');
</script>
这是我实现的代码,它完全符合我的要求。感谢大家的贡献。
var parentUL = $( "ul.menu" );
var startSearchForParentsHere = ".block--services-menu";
$( startSearchForParentsHere ).find( parentUL ).each(function(){
layersDeep = $(this).parentsUntil(startSearchForParentsHere, parentUL).length;
$(this).children().addClass('accordion-layer' + ' ' + layersDeep);
})
也非常感谢进一步的反馈和其他创造性的解决方案!