如何为TinyMCE编辑器添加手风琴组件并实现可视化渲染?
解决TinyMCE手风琴组件可视化预览问题
核心思路
不再直接插入带ID的短代码,而是先从数据库拉取对应手风琴的真实内容,生成带样式的HTML结构插入编辑器,同时保留后端识别所需的标识(比如自定义属性或隐藏的短代码)。
1. 前端修改insertSnippet函数,拉取数据并生成可视化HTML
替换原来直接插入短代码的逻辑,先通过AJAX获取数据库中的手风琴数据,再生成带样式的HTML插入编辑器:
function insertSnippet(accordionId) { // 发起请求获取手风琴数据 fetch(`get_accordion_data.php?id=${accordionId}`) .then(res => res.json()) .then(data => { if (!data.success) return alert('获取手风琴数据失败'); // 生成带样式的手风琴HTML const accordionHtml = buildAccordionHtml(data.accordion); // 插入到编辑器 tinyMCE.activeEditor.insertContent(accordionHtml); }) .catch(err => console.error('请求出错:', err)); } // 构建手风琴HTML结构 function buildAccordionHtml(accordion) { // 内联样式确保编辑器里能正常渲染 const inlineStyle = ` <style> .tiny-accordion { border: 1px solid #eee; border-radius: 4px; margin: 12px 0; } .tiny-accordion-title { padding: 12px 15px; font-weight: 600; background: #f8f8f8; border-bottom: 1px solid #eee; } .tiny-accordion-panel { border-bottom: 1px solid #eee; } .tiny-accordion-panel:last-child { border-bottom: none; } .tiny-accordion-header { padding: 10px 15px; background: #f5f5f5; cursor: pointer; } .tiny-accordion-content { padding: 10px 15px; display: none; } .tiny-accordion-panel.active .tiny-accordion-content { display: block; } </style> `; // 生成面板列表HTML const panelsHtml = accordion.panels.map(panel => ` <div class="tiny-accordion-panel"> <div class="tiny-accordion-header" onclick="this.parentElement.classList.toggle('active')">${panel.title}</div> <div class="tiny-accordion-content">${panel.content}</div> </div> `).join(''); // 包裹自定义属性方便后端识别,同时保留隐藏的短代码(可选) return ` ${inlineStyle} <div class="tiny-accordion" data-accordion-id="${accordion.id}"> <div class="tiny-accordion-title">${accordion.name}</div> ${panelsHtml} </div> <span style="display:none">[accordion id="${accordion.id}"]</span> `; }
2. 编写后端接口get_accordion_data.php
实现从数据库查询手风琴及其面板数据的接口:
<?php // 数据库连接(根据你的实际配置调整) $pdo = new PDO('mysql:host=localhost;dbname=your_database', 'username', 'password'); $accordionId = $_GET['id'] ?? 0; // 查询手风琴主数据 $stmt = $pdo->prepare("SELECT id, name FROM accordions WHERE id = ?"); $stmt->execute([$accordionId]); $accordion = $stmt->fetch(PDO::FETCH_ASSOC); if (!$accordion) { echo json_encode(['success' => false, 'msg' => '手风琴不存在']); exit; } // 查询关联的面板数据 $stmt = $pdo->prepare("SELECT title, content FROM accordion_panels WHERE accordion_id = ? ORDER BY sort_order"); $stmt->execute([$accordionId]); $accordion['panels'] = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['success' => true, 'accordion' => $accordion]); ?>
3. 优化编辑器配置(可选)
如果不想每次插入都带内联样式,可以在tinymce.init中全局添加手风琴样式,并允许自定义元素:
tinymce.init({ // 其他已有配置... content_css: [ // 全局样式文件路径,或者直接写内联样式 'data:text/css;charset=utf-8,' + encodeURIComponent(` .tiny-accordion { border: 1px solid #eee; border-radius: 4px; margin: 12px 0; } .tiny-accordion-title { padding: 12px 15px; font-weight: 600; background: #f8f8f8; border-bottom: 1px solid #eee; } .tiny-accordion-panel { border-bottom: 1px solid #eee; } .tiny-accordion-header { padding: 10px 15px; background: #f5f5f5; cursor: pointer; } .tiny-accordion-content { padding: 10px 15px; } `) ], // 允许自定义元素和属性,避免编辑器过滤 extended_valid_elements: 'div[class|data-accordion-id],div[class],div[class|onclick]' });
4. 后端内容处理
提交编辑器内容时,你可以选择两种方式:
- 直接保存生成的HTML,前端展示时直接渲染;
- 提取隐藏的
[accordion id="xxx"]短代码,后端根据ID重新生成最新的手风琴HTML(适合需要动态更新内容的场景)。
这样操作后,用户在编辑器里插入手风琴时,就能直接看到带样式的可交互预览,而不是单调的ID短代码。
内容的提问来源于stack exchange,提问作者KCYrgn
相关产品推荐
相关产品推荐

