如何递归地遍历 ul 并找出其中有多少个 ul



我试图在jquery中编写一个函数,该函数将通过一个ul与嵌套的ul内部循环。我希望它能跟踪我有多少个ul或"层",并给一个ul的li子类标签,对应于它们的父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将获得一个数字作为新的类标号。

第一个li元素的标签是<li class="1 first layer of li">,第二层li元素的标签是<li class="2 second layer of li">

在普通JS中,你可以使用递归函数(尽管线性函数会更快)。这将沿着DOM向下,并向每个LI添加一个类。当在LI上递归调用时,它会为该调用增加层数。

不确定它是否符合你的目的,但可能足够接近。您还可以获取ul,然后将特定于层的类添加到它们的直接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>

您可以使用JQuery .find()方法轻松完成此操作。

<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/

这是我实现的代码,它完全是我想要的。谢谢大家的贡献。

  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);
      })

进一步的反馈和其他创造性的解决方案也非常感谢!

相关内容

  • 没有找到相关文章

最新更新