2013-08-05 60 views
1

我已經看到了有關將數組/對象轉換爲嵌套列表的幾個問題,但是我發現只有one relevant question是我的問題。我嘗試了一些訪問元素的子元素的方法,但它只會進一步破壞我的代碼。使用Javascript/jQuery遍歷嵌套列表並存儲在數組中

我有一個嵌套的無序列表。

<div id="sortableSitemap"> 
    <ul class="sortable ui-sortable"> 
     <li id="world_news_now"><div>World</div> 
      <ul> 
       <li id="the_news"><div>The News</div></li> 
      </ul> 
     </li> 
     <li id="sports_news_cool"><div>Sports</div></li> 
    </ul> 
</div> 

目前,它包含3項,並出現像這樣:

-World 
    --The News 
-Sports 

可以有任意多個不同深度的節點。我試圖將列表存儲到一個數組中,並附加一些信息。

無論深度如何(即World = 1,News = 2,Sports = 3),每個節點根據其出現的順序獲取數字序列ID(第一個節點爲1,第二個爲2)。我也想存儲一個節點的父節點的ID(root是0)。因此,父ID將爲:世界= 0,新聞= 1,體育= 0.

下面的代碼似乎工作,除非列表是像上面那樣。在這種情況下,它分配新聞= 3及其父= 2(體育)。出於某種原因,重複瀏覽項目(子項)最後會得到<ul>,即使它剛好在開放<li>之後。

我發現除了一個jQuery解決方案,我忽略了深度,即使如此,我需要實際的父節點的ID(我目前保持在一個堆棧中,基於我是否已經降級了)。

爲什麼會發生這種情況,以及如何修改我的代碼以遞歸遍歷列表?

var count = 0; 
var pages = []; 
var parentStack = []; 

      function createNewLevel(items) { 
       var length = items.length; 
       for (var i = 0; i < length; i++) { 

        if (items[i].tagName == 'UL') { 

         parentStack.push(count); 
         createNewLevel($(items[i]).children().get()); 
         parentStack.pop(); 

        } else { 
         ++count; 
         pages.push({ 
          pId: parentStack[parentStack.length - 1], 
          urlStr: $(items[i]).attr('id'), myId: count 
         }); 
        } 
       } 

      } 

      createNewLevel($('#sortableSitemap ul').get()); 

      console.log(pages); 

更新:這裏有一個jsFiddle顯示代碼如何做工作(「新聞報」應該有「世界」作爲自己的父節點)。

+0

我可以問**爲什麼**你想這樣做嗎?將html列表轉換爲對象? – MightyPork

+0

@MightyPork列表ID和父ID用於更新SQL中的Sitemap表。用戶可以在瀏覽器中修改網站的層次結構(各種頁面),然後保存更改。 – Zairja

回答

1

我修改了您的原始代碼。這應該適用於所有嵌套列表的組合。我沒有使用children().get(),而是使用本地JS子方法。它將遍歷列表中的所有內容,但忽略元素,除非它們是<li><ul>。祝你好運。

  var count = 0; 
      var pages = []; 
      var parentStack = []; 

      var result = {}; 

      parentStack.push(0); 

      function createNewLevel(obj) { 
       var obj = obj || document.getElementById('sortableSitemap'); 

       if (obj.tagName == 'LI') { 
        ++count; 
        pages.push({ 
         pId: parentStack[parentStack.length - 1], 
         urlStr: obj.id, myId: count 
        }); 
       } 

       if (obj.hasChildNodes()) { 
        var child = obj.firstChild; 
        while (child) { 
         if (child.nodeType === 1) { 

          if (child.tagName == 'UL') { 
           parentStack.push(count); 
          } 

          createNewLevel(child); 

          if (child.tagName == 'UL') { 
           parentStack.pop(); 
          } 
         } 
         child = child.nextSibling; 
        } 
       } 
      } 

      createNewLevel();