1.生成树状目录结构
基于上篇文章,模拟使用线性顺序的h标签生成了树状的目录结构,只是数据结构的变化,本文将使用实际案例,实现生成目录结构并实现点击定位平滑移动。
2.案例
点击目录结构的title,页面会平滑移动到title所在的地方。

3.js实现
因为js+html+css篇幅较长,所以之展示js代码,源码可以点击这个链接下载。
http://jiajiajia.club/file/info/jF7ZJE/124
具体方法的作用看代码注释吧~
<script>
/**
* 链表节点信息
**/
function Node(data){
this.data=data;
this.next=null;
this.prev=null;
}
/**
* 双向链表数据结构
**/
function LinkedList(){
this.head=null;
this.tail=null;
/**
* 添加节点(添加的节点是尾节点)
**/
this.add=function(data){
var node=new Node(data);
if(this.head==null){
this.head=this.tail=node;
}else{
node.prev=this.tail;
this.tail.next=node;
this.tail=node;
}
}
/**
* 删除目标节点
**/
this.delete=function(node){
if(node==null){
return null;
}
if(node==this.head&&node==this.tail){
this.head=null;
this.tail=null;
}else if(node==this.head){
this.head=this.head.next;
this.head.prev=null;
}else if(node==this.tail){
this.tail=this.tail.prev;
this.tail.next=null;
}else{
node.prev.next=node.next;
node.next.prev=node.prev;
}
node.next=null;
node.prev=null;
return node;
}
}
/**
* 数据节点信息
**/
function createNode(name,level,h){
return {
name:name, //标签名称
level:level, //标签级别
child:new Array(), //标签子节点
h:h, //真实标签元素
};
}
/**
* 生成链表和树的组合结构
**/
function create(h,arr){
while(h!=null){
var li=new LinkedList();
while(h.next!=null){
if(h.next.data.level>h.data.level){
li.add(arr.delete(h.next).data)
}else {
break;
}
}
/**
* 递归生成子树
**/
create(li.head,li);
h.data.child=li;
h=h.next;
}
}
/**
* 将组合结构中的链表结构转换为数组结构
**/
function toArray(arr){
var a=new Array();
var h=arr.head;
while(h!=null){
if(h.data.child!=null){
h.data.child=toArray(h.data.child);
}
a.push(h.data);
h=h.next;
}
return a;
}
</script>
<script>
/**
* 获取所有的h标签(标签是按照顺序获取的)
**/
var hs = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
/**
* 目录父容器
**/
var ml=document.getElementById("ml");
/**
* 生成树结构
**/
function getTree(hs){
var array=new LinkedList();
for(var i=0;i<hs.length;i++){
var h_number=hs[i].tagName.substring(1,2);
array.add(createNode(hs[i].innerHTML,h_number,hs[i]));
}
create(array.head,array);
return toArray(array);
}
var arrayData=getTree(hs);
var index=0;
/**
* 生成目录树节点
**/
function createCataLog(p,list){
if(list!=null&&list.length>0){
var ul=document.createElement("ul");
for(var i=0;i<list.length;i++){
var thisIndex=++index;
var li=document.createElement("li");
var span=document.createElement("span");
span.appendChild(document.createTextNode(list[i].name))
span.setAttribute("to", "id-"+thisIndex);
span.setAttribute("class", "to");
list[i].h.setAttribute("id",'id-'+thisIndex)
li.appendChild(span);
ul.appendChild(li);
if(list[i].child!=null&&list[i].child.length>0){
createCataLog(li,list[i].child);
}
}
p.appendChild(ul);
}
}
createCataLog(ml,arrayData);
/**
* 目录节点添加点击事件
**/
var tos = document.getElementsByClassName("to");
for(var i=0;i<tos.length;i++){
tos[i].addEventListener('click', function(){
to(this.getAttribute("to"));
})
}
/**
* 标签平滑移动
**/
function to(id){
var el=document.getElementById(id);
var body = document.getElementsByTagName("html")[0];
body.scrollTo({
top: el.offsetTop,
behavior: "smooth"
})
}
</script>