一直以来都没去处理这个问题,以至于文章目录一直是使用 padding 形成的层级效果,显然这个办法很土。今天强迫症的我终于动手了。
写了这么个玩意儿:
//增加 html 锚点,格式:h2-num ,比如:h2-1、h3-1 function add_tag(container, tag) { for (let i = 0; i < container.length; i++) { container[i].id = tag + "-" + (i + 1); container[i].className = "j-menu uk-h4"; } } //判断 锚点 层级,取锚点 h2-1 前两位 h2 的后一位 2 //越大则层级越深 function level(tag) { return tag.toString().substring(1, 2); } //获取整个文章结构 进行 tag 标记(不限于 h2 h3 h4) var tags = ["h2", "h3", "h4"]; for (t = 0; t < tags.length; t++) { var container = document.querySelectorAll(".article_content > " + tags[t]); add_tag(container, tags[t]); } var menu_dom = []; menu_dom[0] = '<h3 class="uk-h5">文章结构</h3><ul class="uk-nav uk-nav-default">'; let menus = document.querySelectorAll(".j-menu"); var deepth = 0; //按 html列表规则 进行层级拼接 for (let m = 0; m < menus.length; m++) { let menu = menus[m]; let tag = menu.id; var next = m + 1; var tagNext = tags[0]; if (next < menus.length) { tagNext = menus[next].id; } //console.log(tag + " " + tagNext + " " + level(tag) + " " + level(tagNext)); //console.log(tag + "==>" + menu.innerText + " deep==>" + deepth); var content = '<a href="#' + menu.id + '">' + menu.innerText + "</a>"; var subfix = "<li>" + content + "</li>"; if (level(tag) < level(tagNext)) { deepth++; menu_dom[m + 1] = '<li class="uk-parent">' + content + '<ul class="uk-nav-sub">'; } else if (level(tag) == level(tagNext)) { menu_dom[m + 1] = subfix; } else { var count = deepth; for (d = 0; d < count; d++) { deepth--; subfix += "</li></ul>"; } menu_dom[m + 1] = subfix; } } menu_dom[menus.length + 1] = "</ul>"; if (menus.length > 1) { document.getElementById("menu-container").innerHTML = menu_dom.join(""); } else { document.getElementById("menu-container").innerHTML = "<div class='uk-nav-h5 uk-margin-medium-top'>不好意思噢, 没有在这篇文章中找到目录。</div>"; }
说明:上面的代码只是做了一个 xml html 拼接,代码只测试了h2到 h4,理论上可增加更多层级,请自行测试,此外 class 样式是用的 Uikit。
以上就是目前用的脚本了,在博客上也可以直接找到。我也没怎么学过 JS,拿出来抛砖引玉,优化的地方应该还有很多,因为我看别人的 JS 代码都挺优雅的。说来这个本来也就简单,但算法练得少没什么直觉,只能靠调试来做,不过这样也够用了。
本站由以下主机服务商提供服务支持:
0条评论