代码
<template>
<el-card class="box-card">
<el-divider>目录</el-divider>
<el-tree
style="height: 300px; overflow-y: scroll"
ref="tree"
id="tree"
:data="directories"
@node-click="goAnchor"
highlight-current
default-expand-all
:expand-on-click-node="false"
node-key="id"
icon-class="#fff"
@current-change="check"
>
<span
slot-scope="{ node, data }"
:id="data.id"
class="el-tree-node__label"
>
{{ node.label }}
</span>
</el-tree>
</el-card>
</template>
<script>
export default {
props: {
parentClass: {
type: String,
default: "article-content",
},
},
mounted() {
this.getDirectories();
window.addEventListener("scroll", this.handleScroll);
},
destroyed() {
window.removeEventListener("scroll", this.handleScroll);
},
data() {
return {
directories: [],
};
},
methods: {
getDirectories() {
const titleDomAll = document.querySelectorAll(
`.${this.parentClass} h1, .${this.parentClass} h2`
);
for (let i = 0, len = titleDomAll.length; i < len; i++) {
let el = titleDomAll[i];
let dir = {
tagName: el.tagName,
id: "mxg-tree-" + i,
label: el.innerText,
offsetTop: el.offsetTop,
children: [],
};
if (el.tagName === "H1") {
this.directories.push(dir);
continue;
}
let lastH1 = this.directories[this.directories.length - 1];
if (el.tagName === "H2" && lastH1 && lastH1.tagName === "H1") {
lastH1.children.push(dir);
}
}
},
goAnchor(data) {
document.documentElement.scrollTop = data.offsetTop;
},
handleScroll() {
let scrollTop = document.documentElement.scrollTop;
this.directories.forEach((dir, index) => {
if (scrollTop >= dir.offsetTop) {
this.$refs.tree.setCurrentKey(dir.id);
}
dir.children.forEach((child) => {
if (scrollTop >= child.offsetTop) {
this.$refs.tree.setCurrentKey(child.id);
}
});
});
let nodeTop = this.$refs.tree.getCurrentKey()
? document.getElementById(this.$refs.tree.getCurrentKey()).offsetTop
: 0;
document.getElementById("tree").scrollTop = nodeTop - 100;
},
check(a, b) {
},
},
};
</script>
<style>
.el-card__body {
padding: 10px 10px;
}
.el-tree-node:focus > .el-tree-node__content {
background-color: #fff;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background-color: #f45154;
color: #fff;
font-weight: 500;
border-radius: 4px;
margin-right: 10px;
}
</style>
使用
<my-directory parentClass="article-content"></my-directory>
效果
