0

JS生成列表树

 2 years ago
source link: https://blog.ixk.me/post/js-generate-list-tree
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JS生成列表树

2019-04-19 • Otstar Lin •
本文最后更新于 268 天前,文中所描述的信息可能已发生改变

上一篇文章我们使用 PHP 的构建简单的目录树,这次由于一个项目的需要(构建标题大纲),需要在前端使用 JS 构建 ul li 的多层次列表,其实就是类似于 ZUI 的树形菜单啦( ̄ ▽  ̄)”

首先需要准备一个对象数组,数组中的对象拥有leveltitle(可以自行命名,由于博主是生成标题的索引所以就使用 title 命名)

另外,该数组需要按一定的顺序进行排序,否则就需要自行设置索引,排序的规则是子级必须紧跟在父级后,例如

1// # 1
2// ## 2
3// ## 3
4// ### 4
5// ### 5
6// # 6
7
8var tocContent = [
9  {
10    level: 1,
11    title: "1"
12  },
13  {
14    level: 2,
15    title: "2"
16  },
17  {
18    level: 2,
19    title: "3"
20  },
21  {
22    level: 3,
23    title: "4"
24  },
25  {
26    level: 3,
27    title: "5"
28  },
29  {
30    level: 1,
31    title: "6"
32  }
33];

有了目录的对象数组,我们就可以通过递归或者栈来构建列表树了

构建 HTML

1var tocContent = [];
2function getTocHtml() {
3  var html = getTocHtmlTree(0, "");
4  window.$toc = html;
5  return html;
6}
7function getTocHtmlTree(index, str) {
8  if (index >= tocContent.length) return str;
9  if (index == 0) {
10    str += "";
11  } else if (tocContent[index].level > tocContent[index - 1].level) {
12    for (
13      let i = tocContent[index - 1].level;
14      i < tocContent[index].level;
15      i++
16    ) {
17      str += "<ul>";
18    }
19  } else if (tocContent[index].level < tocContent[index - 1].level) {
20    for (
21      let i = tocContent[index].level;
22      i < tocContent[index - 1].level;
23      i++
24    ) {
25      str += "</ul></li>";
26    }
27  } else {
28    str += "</li>";
29  }
30  str +=
31    '<li><img class="toc-img" src="/static/svg/disc.svg"><a href="#' +
32    tocContent[index].title
33      .toLowerCase()
34      .replace(/ /g, "-")
35      .replace(/[^\u4e00-\u9fa5a-zA-Z0-9-]/g, "") +
36    '">' +
37    tocContent[index].title +
38    "</a>";
39  return getTocHtmlTree(index + 1, str);
40}

通过调用getTocHtml()就可以获得目录的 HTML,生成后的效果如下

f6fd99d9 097d 4b47 959c 6a9acfa51865

从代码中可以看到在 li 标签中还有img标签和带锚点的a标签,a 标签是为了跳转到指定位置而设置的,可以按不同的需求进行调整,img 标签是为了点击时显示和隐藏子级列表而设置的

为目录添加 toggle 功能

废话不多说,先上代码

1function initTocTree() {
2    var items = document.querySelectorAll('#toc .toc-img ~ ul') for (let i = 0; i < items.length; i++) {
3        items[i].parentNode.children[0].setAttribute('src', '/static/svg/minus-square.svg');
4        items[i].parentNode.children[0].setAttribute('onclick', 'toggleToc(this)');
5    }
6}
7function toggleToc(ele) {
8    var display = ele.nextElementSibling.nextElementSibling.style.display
9    if (display === '' || display === 'block') {
10        ele.nextElementSibling.nextElementSibling.style.display = 'none';
11        ele.setAttribute('src', '/static/svg/plus-square.svg');
12    } else {
13        ele.nextElementSibling.nextElementSibling.style.display = 'block';
14        ele.setAttribute('src', '/static/svg/minus-square.svg');
15    }
16}

initTocTree()是用来初始化列表树的,该函数会修改有子列表点的父级列表图片,并为其添加 onclick 事件,toggleToc()是在 img 标签被点击的时候展开/隐藏子级列表的,同时修改其 img 图像,便于用户判断子列表是否已经展开,具体效果如下

fb871850 ce81 4ec8 a9e6 3460d85edfb1

虽然有上篇文章的参考我还是想了很久,写出来的代码也很渣,看来还需不断的学习啊>﹏<


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK