2011-12-21 44 views
2

我有一個這樣的HTML:jQuery的:選擇元素,並在它們之間迭代,直到某元素出現

<h2>H2 A</h2> 
<h3>H3 A</h3> 
<h3>H3 B</h3> 
<h2>H2 B</h2> 
<h3>H3 C</h3> 
<h3>H3 D</h3> 

我想遍歷(例如:)一組H2S的:找到所有H3 下的H2;然後轉到下一個H2並執行相同的操作。但是我想對所有標題遞歸地(大概是)遞歸地和(即H +電平和H +電平+1; h3和h4,h4和h5,等等)。但到目前爲止我還沒有成功。

我的代碼是下面,我想用nextUntil將使工作,但它使每個迭代所有的元素:

function renderHeadingStructure(level, parent) 
{ 
    $('h'+level)/*.nextUntil('h'+level).*/each(function(i,el){ 
     // Copy item name to parent in list - now it is missing creating of an UL :-/
     li = document.createElement('li'); 
     li.innerHTML = el.innerHTML; 
     parent.appendChild(li); 

     // Here would be handy something like: 
     // -> If crossed over H+level-1 (while going trough H+level) 
     // -> then create an ul, recurse and then break 

     if(level<6) 
      renderHeadingStructure(level+1,li); 
    }); 
} 

產生的結構應該是這樣的:

<ul> 
    <li><a>H2 A</a> 
    <ul> 
     <li><a>H3 A</a></li> 
     <li><a>H3 B</a></li> 
    </ul> 
    </li> 
    <li><a>H2 B</a> 
    <ul> 
     <li><a>H3 C</a></li> 
     <li><a>H3 D</a></li> 
    </ul> 
    </li> 
</ul> 

以上代碼的結果是:第一個H2和所有四個H3,然後是第二個H2和全部四個H3 - 都等於1。

有人可以給我一個建議或幫助解決問題嗎? 謝謝你親切

+0

這將是一個很好的面試問題 – 2011-12-22 00:24:39

回答

1

我做正是這只是幾個星期前。遞歸地和nextUntil()。該插件用於生成基於「文章」中hX:s的文檔大綱,並將此列表附加到「body」中,如下所示:

$('article')。generateDocumentOutline('body');

代碼在這裏:http://code.google.com/p/sleek-php/source/browse/trunk/Sites/SleekBase/Modules/Base/JS/jQuery.generateDocumentOutline.js

編輯:它的工作原理,無論你的最高和最低的標題是什麼(所以不限於H2S及3H公司)。

編輯2:您可以在此處看到它使用:http://sleekphp.com/docs/(右側的「跳轉到部分」位)。

+0

就是這樣!非常感謝你。 (現在我必須弄清楚它是如何工作的:-) – A123321 2011-12-22 00:45:33

+0

NP :)好吧,它從文檔中最高的標題開始(doc.find(doc.find(':header')[0] .nodeName)) - 假設最高的標題首先出現(我相信它總是應該))。然後在循環中檢查當前標題是否有比它低的標題(var nextHeadings = heading.nextUntil('h'+ currLevel,'h'+(parseInt(currLevel,10)+ 1)); )如果是這樣的話,在它們上面運行相同的功能,而這些功能又將在比它低的一個上運行它們,然後再低於它們,等等,直到沒有下面的標題爲止。 – powerbuoy 2011-12-22 00:50:33

+0

我從H2開始(H1僅僅是一個,在列表的右上方):'doc.find(doc.find('h2:header')[0] .nodeName)'。另外'parseInt(currLevel,10)'中的基數參數是沒有必要的,是嗎? – A123321 2011-12-22 00:55:07

0

選擇帶有jQuery的h2元素,並檢查下一個元素是否爲h3。使其成爲一個函數並在其內部調用該函數以繼續檢查即將到來的h3元素。

+0

我應該說,但上面的代碼只是一個例子。所有標題之間實際上有很多元素。感謝您的回覆。 – A123321 2011-12-22 00:14:53

0

這裏是我的解決方案:http://jsfiddle.net/RYWwU/4/

var ul = "<ul></ul>"; 
var li = "<li></li>"; 
var result = $("#result"); 

$("h2").each(function() 
{ 
    var heading = $(li).html("<a>" + $(this).text() + "</a>"); 

    var children = $(this).nextUntil("h2").filter("#container h3"); 

    heading.append($(ul)); 
    var sub = heading.find("ul"); 

    children.each(function() 
    { 
     sub.append($(li).html("<a>" + $(this).text() + "</a>")); 
    }); 

    heading.appendTo(result); 
}); 
+0

感謝您的回覆。它適用於H2和H3,但不適用於H4。我試圖擴展它 - http://pastebin.com/98WikaPL但是我再次遇到了我在原始文章中描述的問題 - 它遍歷所有標題。 – A123321 2011-12-22 00:25:57

1

試試這個。這將在h2之後拉出所有h3。我剛剛看到你的評論,但似乎它可能只是做這項工作。

JMAX

var $parent = null; 
var $parentLI = null; 

var $ul = $("<ul/>"); 

$elements = $("h2, h3"); 

$elements.each(function() { 
    var $self = $(this); 
    if ($self.get(0).tagName == "H2"){ 
     $parent = $self; 
     $parentLI = $ul.append("<li> > " + $self.text() + "<ul></ul></li>"); 
    } 
    else if ($self.get(0).tagName == "H3"){ 
     if ($parent) { 
      $parentLI.find("ul").append("<li> &nbsp;&nbsp; > " + $self.text() + "</li>"); 
     } 
    } 
}); 

$parent.parent().append($ul); 

$elements.remove(); 
+0

感謝您的回答。這段代碼創建如下:H2 A:H3 A,H3 B,H3 C,H3 D; H2 B:H3 C,H3 D;而且我不知道如何編輯它以達到我需要的目的。 – A123321 2011-12-22 00:38:16