
本文详解如何在单页中正确初始化多个 Toast UI Editor 实例,并可靠获取其 HTML 内容(含图片等富文本元素),解决 getHtml() 调用失败、实例引用丢失等常见问题。
本文详解如何在单页中正确初始化多个 toast ui editor 实例,并可靠获取其 html 内容(含图片等富文本元素),解决 `gethtml()` 调用失败、实例引用丢失等常见问题。
Toast UI Editor 是一款功能强大且高度可定制的开源富文本编辑器,但在实际项目中——尤其是需支持多字段、多编辑器共存的表单场景(如 CMS 后台、动态表单生成器)——开发者常因实例管理不当而无法正确调用 getHtml(),导致保存内容为空、报错 undefined is not a function 或 getInstance() is not a function。根本原因在于:Toast UI Editor 不支持通过 DOM 属性或 jQuery 间接获取实例,每个编辑器必须被显式创建并持久化引用。
✅ 正确初始化:全局注册 + 唯一 ID 管理
避免使用动态变量名(如 editor{{ field.unique_id }})或依赖 data-editorid 属性反向查找实例。推荐将所有编辑器统一挂载至 window.editors 对象,以 field.unique_id 为键安全存储:
<div class="textarea-editor" data-name="{{ fieldname }}" data-editor-id="{{ field.unique_id }}" id="editor-{{ field.unique_id }}"></div>
// ✅ 推荐初始化方式(纯 JS,无 jQuery 依赖)
window.editors = window.editors || {};
const uniqueId = '{{ field.unique_id }}';
const editorElement = document.querySelector(`#editor-${uniqueId}`);
if (editorElement) {
window.editors[uniqueId] = new toastui.Editor({
el: editorElement,
height: '200px',
initialEditType: 'wysiwyg',
previewStyle: 'vertical',
toolbarItems: [
['heading', 'bold', 'italic', 'strike'],
['hr', 'quote'],
['ul', 'ol', 'task', 'indent', 'outdent'],
['table', 'image', 'link'],
['code', 'codeblock'],
['scrollSync']
],
initialValue: `{{ field.value|safe }}`
});
}
⚠️ 注意事项:
DeepBI DHTML 页面生成器下载生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 务必确保
id="editor-{{ field.unique_id }}"在整个页面中唯一;- 初始化代码应在 DOM 加载完成后执行(建议包裹在
DOMContentLoaded或<script></script>放置于前);- 不要使用
toastui.Editor.getInstance()—— 该方法仅适用于旧版 v2.x 且已废弃,v3+ 版本中已移除,直接调用会报错。
✅ 安全获取 HTML 内容(含图片、表格等完整结构)
所有编辑器实例均通过 window.editors 可控访问,调用 getHtml() 即可返回标准 HTML 字符串(含 标签、内联样式、语义化标签等):
/**
* 批量获取所有编辑器的 HTML 内容
* @returns {Object} 键为 uniqueId,值为对应 HTML 字符串
*/
function getAllEditorContents() {
const contents = {};
for (const id in window.editors) {
if (Object.prototype.hasOwnProperty.call(window.editors, id)) {
try {
contents[id] = window.editors[id].getHtml();
} catch (err) {
console.warn(`Failed to get HTML from editor ${id}:`, err);
contents[id] = ''; // 或保留空字符串/默认值
}
}
}
return contents;
}
// ✅ 使用示例:提交前收集全部内容
document.getElementById('save-form').addEventListener('submit', function (e) {
e.preventDefault();
const payload = getAllEditorContents();
// 发送至后端(如 fetch API)
fetch('/api/save-content', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
});
? 验证与调试技巧
- 在浏览器控制台手动检查:
console.log(window.editors)查看是否成功注册; - 单个编辑器调试:
window.editors['abc123'].getHtml()(替换'abc123'为实际 ID); - 若图片未显示或路径异常,请确认
initialValue中的路径有效,且服务端未过滤src属性(尤其注意 XSS 过滤策略); - 如需获取 Markdown 源码,可用
getMarkdown()替代getHtml()。
通过以上结构化初始化与集中化管理,你不仅能稳定获取 HTML 内容,还能轻松扩展功能(如实时预览、内容校验、撤销栈同步等)。核心原则始终是:实例即状态,引用即接口——拒绝魔法字符串,拥抱显式控制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











