是否有Web控件来动态生成目录?

时间:2010-10-25 20:05:36

标签: asp.net navigation web-controls

说我有一个像这样的基本页面:

<custom:TableOfContents />
<h1>Some Heading</h1>
  <h2>Foo</h2>
    <p>Lorem ipsum</p>
  <h2>Bar</h2>
    <p>Lorem ipsum</p>
  <h2>Baz</h2>
    <p>Lorem ipsum</p>
<h1>Another Heading</h2>
  <h2>Qux</h2>
    <p>Lorem ipsum</p>
  <h2>Quux</h2>
    <p>Lorem ipsum</p>

假设所有标头标签都作为服务器端控件存在。是否有一些用于ASP.NET webforms的Web控件<custom:TableOfContents />,它将动态生成类似于以下内容的目录(当呈现到屏幕时):

1. Some Heading
1.1. Foo
1.2. Bar
1.3. Baz
2. Another Heading
2.1. Qux
2.2. Quux

理想情况下,目录中的每个条目都是指向页面上适当位置的动态生成锚点的超链接。此外,如果每个标头标签的文本都可以以其节号作为前缀,那就太好了。

如果不是网络控件,有没有更简单的方法呢?请记住,许多标头标签将由数据绑定控件创建,因此手动维护目录不是一种选择。似乎webforms模型非常适合创建这样的控件,这就是为什么我很惊讶我还没有找到它。

1 个答案:

答案 0 :(得分:2)

我几天前需要做类似的事情,虽然不是webcontrol但是使用了jQuery。

$(document).ready(buildTableOfContents);

function buildTableOfContents() {
    var headers = $('#content').find('h1,h2,h3,h4,h5,h6');
    var root, list;
    var previousLevel = 1;
    var depths = [0, 0, 0, 0, 0, 0];

    root = list = $('<ol />');

    for (var i = 0; i < headers.length; i++) {
        var header = headers.eq(i);
        var level = parseInt(header.get(0).nodeName.substring(1));

        if (previousLevel > level) {
            // Move up the tree
            for (var L = level; L < previousLevel; L++) {
                list = list.parent().parent();
                depths[L] = 0;
            }
        } else if (previousLevel < level) {
            // A sub-item
            for (var L = previousLevel; L < level; L++) {
                var lastItem = list.children().last();

                // Create an empty list item if we're skipping a level (e.g., h1 -> h3)
                if (lastItem.length == 0)
                    lastItem = $('<li />').appendTo(list);

                list = $('<ol />').appendTo(lastItem);
            }
        }

        depths[level - 1]++;

        // Grab the ID for the anchor
        var id = header.attr('id');
        if (id == '') {
            // If there is no ID, make a random one
            id = header.get(0).nodeName + '-' + Math.round(Math.random() * 1e10);
            header.attr('id', id);
        }

        var sectionNumber = depths.slice(0, level).join('.');

        list.append(
            $('<li />').append(
                $('<a />')
                    .text(sectionNumber + ' '+ header.text())
                    .attr('href', '#' + id)));

        previousLevel = level;
    }

    $('#table-of-contents').append(root);
}

这将生成一个有序列表,并以适当的编号(例如1.1)将其附加到#table-of-contents。只需要一点点CSS就可以隐藏列表的内置编号:#table-of-contents ol { list-style:none; }