如何使用Quill JS自动生成目录并创建锚点链接?
在Quill JS中自动生成目录(TOC)的实现方案
一、先给标题自动生成唯一ID
你现有的代码可以优化为自动生成唯一ID(避免重复),替换固定的some-unique-id:
let Header = Quill.import('formats/header'); const originalCreate = Header.create; Header.create = function(value) { const header = originalCreate(value); // 基于标题文本生成slug,再追加时间戳确保唯一 const slug = header.textContent.trim().toLowerCase() .replace(/\s+/g, '-') .replace(/[^a-z0-9-]/g, ''); header.id = `${slug}-${Date.now()}`; return header; }; Quill.register(Header, true);
二、实时生成并更新目录
通过监听Quill的内容变化事件,提取所有带ID的标题,生成带锚点的目录列表:
1. HTML结构
<!-- 目录容器 --> <div id="toc-container" style="border:1px solid #eee; padding:10px; margin-bottom:10px;"></div> <!-- Quill编辑器 --> <div id="editor"></div>
2. JS逻辑
// 初始化Quill编辑器 const quill = new Quill('#editor', { theme: 'snow', modules: { toolbar: [['header', [1,2,3]]] // 按需配置标题级别 } }); // 生成目录的核心函数 function generateTOC() { const tocContainer = document.getElementById('toc-container'); tocContainer.innerHTML = ''; // 提取编辑器内所有带ID的标题(可按需调整级别) const headers = quill.root.querySelectorAll('h1[id], h2[id], h3[id]'); if (headers.length === 0) return; const tocList = document.createElement('ul'); tocList.style.listStyle = 'none'; tocList.style.paddingLeft = '0'; headers.forEach(header => { const listItem = document.createElement('li'); const link = document.createElement('a'); link.href = `#${header.id}`; link.textContent = header.textContent; // 根据标题级别设置缩进,区分层级 link.style.paddingLeft = `${(parseInt(header.tagName.charAt(1)) - 1) * 15}px`; link.style.display = 'block'; link.style.margin = '4px 0'; link.style.color = '#333'; link.style.textDecoration = 'none'; // 平滑滚动跳转(可选) link.addEventListener('click', (e) => { e.preventDefault(); header.scrollIntoView({ behavior: 'smooth', block: 'start' }); }); listItem.appendChild(link); tocList.appendChild(listItem); }); tocContainer.appendChild(tocList); } // 监听内容变化,实时更新目录 quill.on('text-change', generateTOC); // 编辑器初始化时生成一次目录 generateTOC();
三、补充说明
- 可以根据需求调整监听的标题级别(比如只生成h1、h2)
- 样式可以自定义,比如给不同级别标题加不同的字体大小或颜色
- 如果需要避免重复ID,也可以用递增计数器替代时间戳,比如维护一个全局变量
let headerIdCounter = 0;,然后header.id =header-${headerIdCounter++}``
内容的提问来源于stack exchange,提问作者Mahdi
相关产品推荐
相关产品推荐

