代码之家  ›  专栏  ›  技术社区  ›  Michael Kropat

有动态生成目录的web控件吗?

  •  0
  • Michael Kropat  · 技术社区  · 14 年前

    假设我有一个这样的基本页面:

    <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>
    

    假设所有头标记都作为服务器端控件存在。有网页控件吗 <custom:TableOfContents /> 对于将动态生成类似于以下内容的目录(呈现到屏幕时)的ASP.NET webforms:

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

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

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

    1 回复  |  直到 14 年前
        1
  •  2
  •   Matthew Jacobs    14 年前

    几天前我需要做一个类似的事情,虽然不是网络控制,但是使用了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);
    }
    

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

    推荐文章