我想在JavaScript中生成如下所示的TOC:
<ol>
<li>Heading 1</li>
<li>Heading 2
<ol>
<li>Heading 2-1</li>
<li>Heading 2-2</li>
</ol>
</li>
<li>Heading 3</li>
</ol>以及生成上述TOC的HTML代码:
<section id="toc">
<p>This will be replaced with generated TOC.
</section>
<article>
<h1>Heading 1<h1>
<p>Bla bla bla.</p>
<h1>Heading 2<h1>
<p>Bla bla bla.</p>
<h2>Heading 2-1<h2>
<p>Bla bla bla.</p>
<h2>Heading 2-2<h2>
<p>Bla bla bla.</p>
<h1>Heading 3<h1>
<p>Bla bla bla.</p>
</article>我真的被困住了:(您如何编写代码来生成TOC?我喜欢jQuery还是纯JavaScript。
更新
这对我来说很难,但不知何故,我想我已经做到了:
$(function () {
var assigned_level = 0,
current_level = 0,
id_number = 1,
parent_node = "article",
toc_html = '';
$(parent_node + " *").each(function () {
if (this.nodeName.length === 2 && this.nodeName.charAt(0) === "H") {
$(this).attr("class", "heading");
}
});
$(".heading").each( function () {
current_level = this.nodeName.charAt(1);
$(this).attr('id', "toc-" + id_number);
// Close a list if a same level list follows.
if (assigned_level !== current_level - 1) {
toc_html += "</li>"
}
// Open parent lists if a child list follows.
while (assigned_level < current_level) {
toc_html += "<ol>";
assigned_level += 1;
}
// Close child lists and the parent list if
// the same level parent list follows.
while (assigned_level > current_level) {
toc_html += "</ol></li>";
assigned_level -= 1;
}
toc_html +=
'<li><a href="#' + this.id + '">' + $(this).html() + "</a>";
id_number += 1;
});
// Close everything
while (assigned_level > 0) {
toc_html += "</li></ol>";
assigned_level -= 1;
}
$("#toc").html(toc_html);
});我仍然不明白我做了什么:P,也许还有更复杂的方法。请指出你发现的任何东西。
谢谢。
发布于 2011-04-28 14:14:12
首先,您需要关闭h1,h2标记=)
如果您执行$("h1, h2, h3, h4, h5, h6"),您将得到与文档中显示的标记顺序相同的标记。所以你可以在这个数组上做一个循环并检查级别。如果最后一个标记是H1,并且您找到了一个H2,这意味着您需要创建一个<ol>。另一方面,如果您有一个H3,而下一个是H2,这意味着您需要关闭<ol>。
最困难的部分是最终关闭剩余的<ol>。
希望这能有所帮助。
发布于 2011-04-28 14:13:59
在我们看到你到目前为止想出的东西之前,我不想太深入。
然而,看看.each() .children()和.find()。这些应该给你一些关于如何完成你想要做的事情的想法。
发布于 2020-01-31 14:53:02
我知道这个问题已经8岁了,但我有个建议。也许不是最有效的方法,也不是最短的,但它是有效的。
在页面末尾,添加以下JavaScript:
// prepare the array by adding level, ID and parent to each item of the array
function prepare( array ) {
let idt, level, t;
for( let i = 0, n = array.length; i < n; i++ ) {
t = array[ i ];
t.el = t;
level = parseInt( t.tagName[1], 10 );
t.level = level;
t.idt = i + 1;
if( level <= 1 ) t.parent = 0;
if( i ) {
if( array[ i - 1 ].level < level ) {
t.parent = array[ i - 1 ].idt;
} else if( array[ i - 1 ].level == level ) {
t.parent = array[ i - 1 ].parent;
} else {
for( let j = i - 1; j >= 0; j-- ) {
if( array[ j ].level == level - 1) {
t.parent = array[ j ].idt;
break;
}
}
}
}
}
return array;
}
// transform a flat array in a hierarchical array
function hierarchical( items ) {
let hashTable = Object.create( null );
items.forEach( item => hashTable[ item.idt ] = { ...item, subitems : [] } );
let tree = [];
items.forEach( item => {
if( item.parent )
hashTable[ item.parent ].subitems.push( hashTable[ item.idt ] );
else
tree.push(hashTable[ item.idt ]);
});
return tree;
}
// return an UL containing each title in a LI and possibly other items in UL sub-lists.
function add_list( titles ) {
let li, a, anchor;
let ol = document.createElement( "ol" );
if( titles && titles.length ) {
for( t of titles ) {
if( t.el.id ) anchor = t.el.id;
else anchor = t.el.textContent;
if( ! anchor ) anchor = "inconnu";
anchor = anchor.replace( /\W/g, "" );
t.el.id = anchor;
li = document.createElement( "li" );
a = document.createElement( "a" );
a.href = `#${anchor}`;
a.innerHTML = t.el.textContent;
li.append( a );
if( t.subitems && t.subitems.length ) {
li.append( add_list( t.subitems ) );
}
ol.append( li );
}
}
return ol;
}
//get the toc element
let divtoc = document.getElementById( "toc" );
// get the article element
let article = document.getElementById( "article" );
if( toc && article ) {
let titles = article.querySelectorAll( "h1, h2, h3, h4, h5, h6" );
titles = prepare( titles );
titles = hierarchical( titles );
let ol_racine = add_list( titles );
toc.append( ol_racine );
}您将得到预期的结果:
<section id="toc">
<ol>
<li><a href="#Heading1">Heading 1</a></li>
<li>
<a href="#Heading2">Heading 2</a>
<ol>
<li><a href="#Heading21">Heading 2-1</a></li>
<li><a href="#Heading22">Heading 2-2</a></li>
</ol>
</li>
<li><a href="#Heading3">Heading 3</a></li>
</ol>
</section>https://stackoverflow.com/questions/5819807
复制相似问题