能否在TinyMCE React编辑器中添加选中文本触发的气球工具栏?
在TinyMCE React基础版中实现气球编辑器(选中文本弹出工具栏)
TinyMCE React的基础版(开源核心版)不自带官方的气球编辑器功能——官方的balloontoolbar插件属于TinyMCE Premium付费套件的一部分,基础版无法直接启用该插件。
但如果不想升级到付费版,完全可以通过自定义代码实现类似的"选中文本弹出工具栏"效果,具体方案如下:
自定义实现步骤
- 监听编辑器选区变化:通过TinyMCE的
selectionchange事件,判断当前是否有选中的文本。 - 定位工具栏位置:获取选区的DOM矩形位置,计算自定义工具栏的浮动坐标。
- 实现工具栏交互:给自定义工具栏的按钮绑定编辑器命令(如加粗、斜体等),点击时调用编辑器的
execCommand方法执行对应操作。 - 处理隐藏逻辑:点击编辑器外部或选区取消时,隐藏工具栏。
示例代码
import { useRef, useState, useEffect } from 'react'; import { Editor } from '@tinymce/tinymce-react'; // 自定义气球工具栏组件 const CustomBalloonToolbar = ({ isVisible, position, onCommand }) => { if (!isVisible) return null; return ( <div style={{ position: 'absolute', top: `${position.top - 40}px`, left: `${position.left}px`, background: '#ffffff', border: '1px solid #e0e0e0', borderRadius: '6px', padding: '6px', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', zIndex: 10000, display: 'flex', gap: '8px' }} > <button onClick={() => onCommand('bold')} style={{ border: 'none', background: 'transparent', cursor: 'pointer', padding: '4px 8px' }} > <strong>B</strong> </button> <button onClick={() => onCommand('italic')} style={{ border: 'none', background: 'transparent', cursor: 'pointer', padding: '4px 8px' }} > <em>I</em> </button> <button onClick={() => onCommand('underline')} style={{ border: 'none', background: 'transparent', cursor: 'pointer', padding: '4px 8px' }} > <u>U</u> </button> </div> ); }; const EditorWithBalloonToolbar = () => { const editorRef = useRef(null); const [toolbarVisible, setToolbarVisible] = useState(false); const [toolbarPosition, setToolbarPosition] = useState({ top: 0, left: 0 }); // 监听编辑器选区变化 const handleEditorSetup = (editor) => { editor.on('selectionchange', () => { const selection = editor.selection.getSel(); if (!selection.isCollapsed) { const rangeRect = selection.getRangeAt(0).getBoundingClientRect(); // 计算工具栏位置(居中对齐选区) setToolbarPosition({ top: rangeRect.top + window.scrollY, left: rangeRect.left + window.scrollX + (rangeRect.width / 2) - 45 }); setToolbarVisible(true); } else { setToolbarVisible(false); } }); }; // 点击编辑器外部隐藏工具栏 useEffect(() => { const handleClickOutside = (e) => { const editorContainer = document.querySelector('.tox-editor-container'); if (editorContainer && !editorContainer.contains(e.target) && toolbarVisible) { setToolbarVisible(false); } }; document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }, [toolbarVisible]); // 执行编辑器命令 const executeEditorCommand = (command) => { editorRef.current?.editor.execCommand(command); }; return ( <div style={{ position: 'relative', maxWidth: '800px', margin: '20px auto' }}> <Editor ref={editorRef} apiKey="your-api-key" // 替换为你的TinyMCE API Key(基础版免费可用) init={{ height: 500, menubar: false, toolbar: false, // 隐藏默认工具栏 plugins: 'advlist autolink lists link image charmap', branding: false }} onSetup={handleEditorSetup} /> <CustomBalloonToolbar isVisible={toolbarVisible} position={toolbarPosition} onCommand={executeEditorCommand} /> </div> ); }; export default EditorWithBalloonToolbar;
注意事项
- 需替换代码中的
your-api-key为你自己的TinyMCE API Key(基础版可免费申请)。 - 自定义工具栏的样式、按钮功能可根据需求调整,比如添加链接、列表等更多命令。
- 若需要更复杂的交互(如文本格式实时预览),可结合TinyMCE的API扩展逻辑。
内容的提问来源于stack exchange,提问作者rahul
相关产品推荐
相关产品推荐

