You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quill解析还原HTML时嵌套列表失效,Next.js中如何解决?

保持Quill列表嵌套结构的三种方法

方法1:通过CSS模拟缩进效果

直接给不同层级的ql-indent类添加左边距,模拟嵌套视觉效果,无需修改HTML结构:

.ql-indent-1 {
  margin-left: 2em;
}
.ql-indent-2 {
  margin-left: 4em;
}
/* 更多层级可按此规律递增 */

这种方式快速简单,适合仅需要视觉嵌套的场景。

方法2:转换HTML结构为真实嵌套列表

如果需要语义化的嵌套列表(而非仅视觉缩进),可以在渲染前处理Quill生成的HTML字符串,将带ql-indent类的<li>转换为嵌套的<ol>/<ul>结构。

示例处理函数:

function transformQuillList(html) {
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, 'text/html');
  const ol = doc.querySelector('ol');
  if (!ol) return html;

  const items = Array.from(ol.children);
  const stack = [{ level: 0, element: ol }];

  items.forEach(item => {
    // 获取当前缩进层级,ql-indent-N对应层级N
    const indentClass = Array.from(item.classList).find(c => c.startsWith('ql-indent-'));
    const currentLevel = indentClass ? parseInt(indentClass.split('-')[2]) : 0;

    // 定位当前层级对应的父容器
    while (stack.length > 0 && stack[stack.length - 1].level >= currentLevel) {
      stack.pop();
    }

    const parent = stack[stack.length - 1].element;
    // 若父容器是li,先创建ol作为子容器
    if (parent.tagName === 'LI') {
      let childOl = parent.querySelector('ol');
      if (!childOl) {
        childOl = doc.createElement('ol');
        parent.appendChild(childOl);
      }
      childOl.appendChild(item);
    } else {
      parent.appendChild(item);
    }

    // 更新栈,当前item作为下一层级的父容器
    stack.push({ level: currentLevel, element: item });
    // 移除indent类
    item.classList.remove(indentClass);
  });

  return doc.body.innerHTML;
}

在Next.js中使用:

<div dangerouslySetInnerHTML={{ __html: transformQuillList(data) }} />

该方法会生成符合HTML语义规范的真正嵌套<ol>结构。

方法3:配置Quill直接生成嵌套列表

修改Quill的配置,让编辑器在编辑时直接生成嵌套列表结构,而非添加ql-indent类。需要自定义Quill的列表模块:

import Quill from 'quill';
const List = Quill.import('formats/list');

// 重写List的format方法,实现嵌套逻辑
class NestedList extends List {
  static format(name, value, context) {
    if (value) {
      const range = context.quill.getSelection();
      const [block] = context.quill.getLine(range.index);
      if (block && block.statics.blotName === 'list-item') {
        const parentList = block.parent;
        if (parentList && parentList.statics.blotName === name) {
          // 创建嵌套列表并将当前item移入
          const nestedList = this.create(value);
          block.parent.insertBefore(nestedList, block.next);
          nestedList.appendChild(block);
          return;
        }
      }
    }
    super.format(name, value, context);
  }
}

Quill.register(NestedList, true);

配置后,Quill编辑缩进列表时会直接生成嵌套的<ol>/<ul>,渲染时无需额外处理。


内容的提问来源于stack exchange,提问作者not_hisokaYet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:13:25