Donc, j'utilise un document afin de saisir toutes les en-têtes avec empressement (). Je fais cela afin de créer une carte de document Microsoft Word Style avec Buildnav (). Cela fonctionne actuellement, mais ce n'est pas très robuste et ne casse à tout moment les rubriques ne suivent pas un ordre strict ... par exemple. (Si vous commencez par un H2, il se casse, si vous niez un H3 sous et H1, il se casse, etc.)
Je ne peux pas comprendre la meilleure façon de résoudre ce problème (le rendre plus robuste). Je tire parti de la fonction `NextUntil 'de JQuery pour trouver tous les H2S entre deux h1s. P>
Une possibilité remplace: p> avec P> stackHeadings = (items, cur, counter) ->
cur = 1 if cur == undefined
counter ?= 1
next = cur + 1
for elem, index in items
elem = $(elem)
children = filterHeadlines( elem.nextUntil( 'h' + cur, 'h' + next ) )
d.children = stackHeadings( children, next, counter ) if children.length > 0
d
filterHeadlines = ( $hs ) ->
_.filter( $hs, ( h ) -> $(h).text().match(/[^\s]/) )
buildNav = ( ul, items ) ->
for child, index in items
li = $( "<li>" )
$( ul ).append( li )
$a = $("<a/>")
$a.attr( "id", "nav-title-" + child.id )
li.append( $a )
if child.children
subUl = document.createElement( 'ul' )
li.append( subUl )
buildNav( subUl, child.children )
items = stackHeadings( filterHeadlines( source.find( 'h1' ) ) )
ul = $('<ul>')
buildNav( ul, items)
3 Réponses :
Vous pouvez simplement utiliser le jQuery toC plugin , il apparaît qu'ils sont le faire comme ceci: bien sûr , cela traite simplement tous les Il semblerait étrange d'avoir un H1 code>,
H2 code> et
H3 code> de manière égale et crée la TOC en considérant la nidification et l'ordre de document des éléments uniquement. Mais n'est-ce pas que le comportement souhaité? P>
H3 code>, qui est directement à l'intérieur d'un
H1 code>, double en retrait dans le TOC. Si vous ne pouvez pas vivre avec cette incohérence, au lieu d'insérer le manquant
H2 code> entre, je envisagerais de nettoyer le code HTML et de convertir le
h3 code> en un
H2 code>. p> p>
J'ai jeté ensemble de Javascript qui fera ce que vous voulez http://jsfiddle.net/fa4ew/
C'est une fonction récursive assez simple qui consomme un éventail d'éléments (nœuds) et crée la structure ultérieure en conséquence. Pour être cohérent avec la question que j'ajoute les éléments de la liste d'emplois (vides) lorsque vous à partir d'un H1 à un H3, etc. P>
function buildRec(nodes, elm, lv) { var node; // filter do { node = nodes.shift(); } while(node && !(/^h[123456]$/i.test(node.tagName))); // process the next node if(node) { var ul, li, cnt; var curLv = parseInt(node.tagName.substring(1)); if(curLv == lv) { // same level append an il cnt = 0; } else if(curLv < lv) { // walk up then append il cnt = 0; do { elm = elm.parentNode.parentNode; cnt--; } while(cnt > (curLv - lv)); } else if(curLv > lv) { // create children then append il cnt = 0; do { li = elm.lastChild; if(li == null) li = elm.appendChild(document.createElement("li")); elm = li.appendChild(document.createElement("ul")); cnt++; } while(cnt < (curLv - lv)); } li = elm.appendChild(document.createElement("li")); // replace the next line with archor tags or whatever you want li.innerHTML = node.innerHTML; // recursive call buildRec(nodes, elm, lv + cnt); } } // example usage var all = document.getElementById("content").getElementsByTagName("*"); var nodes = []; for(var i = all.length; i--; nodes.unshift(all[i])); var result = document.createElement("ul"); buildRec(nodes, result, 1); document.getElementById("outp").appendChild(result);
Je travaille sur la mise en œuvre de votre code, qui a l'air plutôt bien. Une chose que j'ai rencontrée est que les nœuds peuvent avoir des propriétés, ce qui semble mettre en extra "" "que cet algorithme ne peut pas gérer.
Ainsi, en essayant de comprendre votre exemple, je suis allé et j'ai essayé de le convertir en une solution davantage basée sur jQuery pouvant gérer »... Il y a quelque chose que je ne comprends pas la magie de la façon dont vous échangez ELM et LI, et le Éléments annexés que vous rassemblez en cours de route. Je mets votre exemple dans un autre violon pour démontrer la conversion. L'esprit lui donne un look et voyez si vous pouvez comprendre où le mien se vante? jsfiddle.net/funkyeah/s8m2t/3
J'ai aussi posté la question suivante que j'ai côtoyée ci-dessus, ici: Stackoverflow.com/Questtions/17451231/...
@funkyeah - jsfiddle.net/s8m2t/8 Votre bogue était la différence entre JQuery.append et Dom .appendcendchild. JQuery ne retourne pas l'enfant avec $ .append (enfant) Il renvoie la même liste afin que vous puissiez utiliser une chaînage. Le Dom.appendchild (enfant) renvoie l'enfant.
Oui, merci ... JQuery's AppendTo m'a aidé à résoudre ... j'ai fait la variante JQuery dans l'autre réponse en fonction de votre réponse
Solution JQuery + Coffescript basée sur la réponse de @LastCoder
http://jsfiddle.net/sysydky/1/ Utilisation p>
Cela pourrait vous aider si vous attachez un exemple de certains des HTML que vous essayez d'analyser.
Il semble que vous ayez besoin de clarifier ce que vous voulez en dehors de cela. Voulez-vous respecter l'exactitude de sorte que seules H1 et H2 puissent suivre un H1, et que seuls H1, H2 ou H3 peuvent suivre H2; Voulez-vous appliquer qu'une balise HX ne peut pas être à l'intérieur d'une autre balise Hx? Ou voulez-vous juste faire de votre mieux pour honorer l'intention semblant du document que vous recevez?