抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

使用 JavaScript 生成一个简单文章目录

一直以来都没去处理这个问题,以至于文章目录一直是使用 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 拼接,代码只测试了h2到 h4,理论上可增加更多层级,请自行测试,此外 class 样式是用的 Uikit

以上就是目前用的脚本了,在博客上也可以直接找到。我也没怎么学过 JS,拿出来抛砖引玉,优化的地方应该还有很多,因为我看别人的 JS 代码都挺优雅的。说来这个本来也就简单,但算法练得少没什么直觉,只能靠调试来做,不过这样也够用了。


0条评论

发表评论