有没有一个网页控件可以动态生成目录?

发布于 2024-09-28 16:17:31 字数 917 浏览 9 评论 0原文

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

<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 Web 表单的 Web 控件 可以动态生成如下内容的目录(当呈现到屏幕上时):

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

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

如果不是网络控件,是否有一些更简单的方法可以做到这一点?请记住,许多标题标记将由数据绑定控件创建,因此手动维护目录不是一种选择。看起来 Webforms 模型非常适合创建这样的控件,这就是为什么我很惊讶我还没有找到一个控件。

Say I have a basic page like so:

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

Assume all the header tags exist as server side controls. Is there some web control <custom:TableOfContents /> for ASP.NET webforms that will dynamically generate a table of contents that looks something like the following (when rendered to the screen):

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

Ideally, each entry in the table of contents would be a hyperlink to a dynamically generated anchor at the appropriate place on the page. Also, it would be nice if the text of each header tag could be prefixed with its section number.

If not a web control, is there some easier way of doing this? Keep in mind that many of the header tags are going to be created by data bound controls, so manually maintaining the table of contents is not an option. It seems like the webforms model is ideally suited to creating such a control, which is why I'm surprised I haven't yet found one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静待花开 2024-10-05 16:17:31

几天前我需要做类似的事情,虽然不是 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; }。

I needed to do a similar thing a few days ago and, though not a webcontrol, used 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);
}

This will make an ordered list and append it to #table-of-contents with appropriate numbering (e.g., 1.1). Just a little bit of CSS is needed to hide the lists' built in numbering: #table-of-contents ol { list-style:none; }.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文