2015-05-19 20 views
1

我想在jQuery中編寫一個函數,它將循環通過一個ul嵌套ul的裏面。我希望它跟蹤我有多少個ul或「圖層」,併爲ul的li孩子給與他們父母ul所在的「圖層」相對應的班級標籤。 的HTML的結構是such`如何循環遍歷一個ul,並找出它有多少ul它

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

每個L1會得到一個號碼爲一類新的標籤。

所以第一個li元素會得到一個標籤<li class="1 first layer of li">,李的第二層將被標記<li class="2 second layer of li">

回答

2

在純JS,你可以使用一個遞歸函數(儘管線性的會更快)。這會沿着DOM向每個LI添加一個類。在LI上遞歸調用時,它會增加該調用的層數。

不確定它是否適合您的目的,但可能已經足夠接近。你也可以得到ULs,然後爲他們的即時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> 
+0

真棒解決方案。在JavaScript中這樣做很難。還沒有測試過,但一眼就看起來不錯。謝謝。 – Luke

2

您可以輕鬆地與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; 


看看這個的jsfiddlehttp://jsfiddle.net/aaaprbst/1/

+1

我不明白這是基於UL層深度向LI添加一個類。 – RobG

+0

大抓Rob。即使如此......感謝henry for .find()提示!我以前曾誤解過,認爲它只有1層深。 – Luke

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

其他反饋和其他創造性的解決方案也非常感謝!

相關問題