一、自定义生成目录菜单
1.配置自定义生成目录菜单
import {
SlateTransforms
} from '@wangeditor/editor'
class MyButtonMenu{
title = "生成目录"
// iconSvg = QUOTE_SVG
tag = 'button'
getValue() {
// 用不到 getValue
return ''
}
isActive() {
return false
}
isDisabled(){
return false
}
exec(editor) {
let headers = editor.getElemsByTypePrefix('header')
let nodes = headers.map(item => {
let node = {
type: 'paragraph',
children: [{
text: item.children[0].text,
color: 'rgb(103, 149, 181)'
}]
}
if (item.type === 'header1') {
node.indent = '2em'
}
if (item.type === 'header2') {
node.indent = '4em'
}
if (item.type === 'header3') {
node.indent = '6em'
}
if (item.type === 'header4') {
node.indent = '8em'
}
if (item.type === 'header5') {
node.indent = '10em'
}
return node
})
const divider = {
type: 'divider',
children: [{
text: ''
}]
}
const menu = {
type: 'paragraph',
children: [{
text: '目录',
bold: true
}]
}
nodes.unshift(menu)
nodes.push(divider)
SlateTransforms.insertNodes(editor, nodes)
}
}
export const myButtonMenu={
key: 'createMenu', // menu key ,唯一。注册之后,可配置到工具栏
factory() {
return new MyButtonMenu()
}
}
2.注册菜单
import{Boot} from '@wangeditor/editor'
Boot.registerMenu(myButtonMenu)
如图
3.编辑器新增生成目录菜单
toolbarConfig: {
// toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
// excludeKeys: [ /* 隐藏哪些菜单 */ ],
insertKeys: {
index: 35, // 插入的位置,基于当前的 toolbarKeys
keys: ['createMenu']
}
}
二、渲染富文本内容时生成目录
1.生成目录
在富文本内容渲染后获取到h标签,通过遍历给标签增加锚点(id),然后生成一个用来渲染目录的数组。通过设置标签的margin值或者padding值来设置缩进,而后达到递进的层级关系。
handlerMenu() {
let content = document.querySelector(".content")
console.log(content);
let els = content.querySelectorAll("h1,h2,h3,h4,h5,h6")
let menus = []
if (els) {
els.forEach((item, index) => {
let menu = {}
menu.isActive = null
// 增加一个id标识
menu.title = item.innerText
menu.scrollTop = item.offsetTop
let level = item.tagName.toLowerCase().replace("h", "")
menu.level = parseInt(level)
item.setAttribute("id", `menus_${index+1}`)
menu.id = `#menus_${index+1}`
menus.push(menu)
})
}
this.menuList = menus
console.log(this.menuList);
this.listenScroll()
}
// 监听目录导航,设置选中时的样式
listenScroll() {
window.addEventListener("scroll", () => {
if (this.menuList) {
this.menuList.forEach((item, index, list) => {
let scrollTop = (document.documentElement.scrollTop || document.body.scrollTops)+2
console.log(scrollTop, item.scrollTop);
if (index == 0 && scrollTop >= item.scrollTop && scrollTop < list[index + 1]
.scrollTop) {
item.isActive = true
} else if (index > 0 && index < list.length - 1 && scrollTop >= item.scrollTop &&
scrollTop < list[index + 1].scrollTop) {
item.isActive = true
} else if (index === list.length - 1 && scrollTop >= item.scrollTop) {
item.isActive = true
}else{
item.isActive=false
}
})
}
})
},
2.渲染目录
<div class="my-menus">
<div :class="['item',index===currentMenu?'active':'']" v-for="(item,index) in menuList" :key="item.id" v-text="item.title"
:style="`margin-left:${item.level*14}px;`"
@click="scrollToEle(item,index)">
</div>
</div>
3.关联锚点
点击目录时可以滚动到相应的h标签
scrollToEle(item,index){
this.currentMenu=index
window.scrollTo(0,item.scrollTop-100)
}