js根据文章生成标题目录

88次阅读
没有评论

在浏览一些博客或 wiki 类网站的时候,你可能会发现在文章的开头或侧边会有一个目录,点击就可以跳转到指定的章节。对于比较长的文章来说,目录还是比较重要的。通过目录可以快速了解文章包含的内容,要查看某个章节也可以直接跳转。

1、实现逻辑

//  给 h2 到 h5 增加一个 content-title 的 class
$('.post-content h2').addClass('content-title');
$('.post-content h3').addClass('content-title');
$('.post-content h4').addClass('content-title');
$('.post-content h5').addClass('content-title');
//  给 h2 到 h5 增加一个 data-index 的自定义属性
$('.post-content h2').attr('data-index', 2);
$('.post-content h3').attr('data-index', 3);
$('.post-content h4').attr('data-index', 4);
$('.post-content h5').attr('data-index', 5);

//  函数的一个参数是标题级别,第二个参数是第一个标题的索引值
function atalog(titleIndex, start) {
    //  存储 HTML 和当前的索引值
    var el = {
        el: '',
        index: start
    };
    var current = 0;  //  已遍历的数量

    for (var i = start;i < $('.content-title').length;i ++) {
        if (i < current) {
            //  如果当前 i 的值小于已遍历的数量就跳过
            continue;
        }

        if ($('.content-title').eq(i).attr('data-index') > titleIndex) {
            //  如果是更小一级的标题就调用自身继续查找
            var result = atalog($('.content-title').eq(i).attr('data-index'), i);
            //  把返回的 HTML 添加到当前函数的 el 中
            el.el += '
  • ' + result.el + '
  • '; current = result.index + 1; // 设置已遍历的数量 el.index = result.index; // 设置索引 continue; // 跳过本次循环 } if ($('.content-title').eq(i).attr('data-index') < titleIndex) { // 如果是更大一级的标题就返回已生成的 HTML 目录 el.el = '
      ' + el.el + '
    '; return el; } // 生成 HTML 目录 el.el += '
  • ' + $('.content-title').eq(i).text() + '
  • '; el.index = i; // 设置当前的索引值为 i } // 添加列表的外层 ul el.el = '
      ' + el.el + '
    '; return el; // 返回生成的 HTML 目录 } // 调用生成目录的函数,从第 0 个 h2 开始 var el = atalog(2, 0); // 把生成的目录插入到文章的开头 $('.post-content').prepend('
    ' + el.el + '
    '); // 给生成的目录添加点击事件 $('.post-content .atalog a').on('click', function () { // 设置滚动条的高度为标题的 offsetTop $(document).scrollTop($('.content-title').eq($(this).attr('data-index')).offset().top); });

    上面的文章内容就在 class 为 post-content 的元素中。

    2、简单说明

    上面生成目录是从 h2 开始遍历,不包含 h1。

    先给 h2、h3、h4、h5 添加相同的 class,再给 h2、h3、h4、h5 添加 2、3、4、5 的 data-index 属性,用来区分标题等级。

    函数的第一个参数是最大的标题等级,上面设置的是 2 ,也就是代表 h2。第二个参数是开始遍历的索引,上面设置为 0 就是从第 0 个标题开始遍历。

    如果遍历到更小一级的标题就调用自身,传入更小一级的标题和当前的索引值继续遍历。如果遍历到更大一级的标题就返回生成的 HTML 目录。

    遍历完成后生成 HTML 目录列表,然后返回 HTML 目录列表。

    目录跳转可以通过改变滚动条的高度来跳转,也可以给标题和链接添加 id 跳转。如果通过 id 跳转的话,一些使用固定定位的导航栏可能会挡住标题,而通过改变滚动条高度来跳转就可以很方便的设置标题显示的位置。

    3、完整代码示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>js生成目录</title>
        <style>
            #frame {
                width: 200px;
                margin-left: 100px;
            }
        </style>
    </head>
    <body>
    <div id="frame">
        <div class="post-content">
    
            <h1>市分公司的</h1>
            在浏览一些博客或 wiki 类网站的时候,你可能会发现在文章的开头或侧边会有一个目录,点击就可以跳转到指定的章节。对于比较长的文章来说,目录还是比较重要的。通过目录可以快速了解文章包含的内容,要查看某个章节也可以直接跳转。
            最近准备给博客增加一个生成文章目录的功能,下面简单写一下实现方式。
            <h2>代表的改变的</h2>
            在浏览一些博客或 wiki 类网站的时候,你可能会发现在文章的开头或侧边会有一个目录,点击就可以跳转到指定的章节。对于比较长的文章来说,目录还是比较重要的。通过目录可以快速了解文章包含的内容,要查看某个章节也可以直接跳转。
            最近准备给博客增加一个生成文章目录的功能,下面简单写一下实现方式。
            <h3>大是大非</h3>
            在浏览一些博客或 wiki 类网站的时候,你可能会发现在文章的开头或侧边会有一个目录,点击就可以跳转到指定的章节。对于比较长的文章来说,目录还是比较重要的。通过目录可以快速了解文章包含的内容,要查看某个章节也可以直接跳转。
            最近准备给博客增加一个生成文章目录的功能,下面简单写一下实现方式。
            <h4>发不发</h4>
            在浏览一些博客或 wiki 类网站的时候,你可能会发现在文章的开头或侧边会有一个目录,点击就可以跳转到指定的章节。对于比较长的文章来说,目录还是比较重要的。通过目录可以快速了解文章包含的内容,要查看某个章节也可以直接跳转。
            最近准备给博客增加一个生成文章目录的功能,下面简单写一下实现方式。
        </div>
    
    </div>
    </body>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    
    <script>
        //  给 h2 到 h5 增加一个 content-title 的 class
        $('h1').addClass('content-title');
        $('h2').addClass('content-title');
        $('h3').addClass('content-title');
        $('h4').addClass('content-title');
        //  给 h2 到 h5 增加一个 data-index 的自定义属性
        $('h1').attr('data-index', 1);
        $('h2').attr('data-index', 2);
        $('h3').attr('data-index', 3);
        $('h4').attr('data-index', 4);
    
        //  函数的一个参数是标题级别,第二个参数是第一个标题的索引值
        function atalog(titleIndex, start) {
            //  存储 HTML 和当前的索引值
            var el = {
                el: '',
                index: start
            };
            var current = 0;  //  已遍历的数量
    
            for (var i = start;i < $('.content-title').length;i ++) {
                if (i < current) {
                    //  如果当前 i 的值小于已遍历的数量就跳过
                    continue;
                }
    
                if ($('.content-title').eq(i).attr('data-index') > titleIndex) {
                    //  如果是更小一级的标题就调用自身继续查找
                    var result = atalog($('.content-title').eq(i).attr('data-index'), i);
                    //  把返回的 HTML 添加到当前函数的 el 中
                    el.el += '<li> ' + result.el + '</li>';
                    current = result.index + 1;  //  设置已遍历的数量
                    el.index = result.index;  //  设置索引
                    continue;  //  跳过本次循环
                }
    
                if ($('.content-title').eq(i).attr('data-index') < titleIndex) {
                    //  如果是更大一级的标题就返回已生成的 HTML 目录
                    el.el = '<ul class="mb-2">' + el.el + '</ul>';
                    return el;
                }
                //  生成 HTML 目录
                el.el += '<li><a data-index="' + i + '" href="javascript:;">' + $('.content-title').eq(i).text() + '</a></li>';
                el.index = i;  //  设置当前的索引值为 i
            }
            //  添加列表的外层 ul
            el.el = '<ul class="mb-2"> ' + el.el + '</ul>';
            return el;  //  返回生成的 HTML 目录
        }
    
        //  调用生成目录的函数,从第 0 个 h1 开始
        var el = atalog(1, 0);
        //  把生成的目录插入到文章的开头
        $('.post-content').prepend('<div class="atalog">' + el.el + '</div>');
        //  给生成的目录添加点击事件
        $('.post-content .atalog a').on('click', function () {
            //  设置滚动条的高度为标题的 offsetTop
            $(document).scrollTop($('.content-title').eq($(this).attr('data-index')).offset().top);
        });
    </script>
    </html>

    4、效果图

    注意:这里为了效果,我调整了外层父元素的宽度,点击上面的h4标题就可以看到页面的跳转
    js根据文章生成标题目录

     

    正文完
     
    评论(没有评论)