尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CKEditor 5 Balloon Editor(气泡编辑器)实现解析与初始化实战

CKEditor 5 Balloon Editor(气泡编辑器)实现解析与初始化实战 CKEditor 5 Balloon Editor气泡编辑器实现解析与初始化实战【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5本篇技术指南围绕 CKEditor 5 开源仓库中ckeditor5-editor-balloon包展开系统讲解 Balloon EditorMedium 风格编辑器的架构设计、三种初始化方式、root配置体系与常见错误约束。读完本文你将掌握如何在自己的页面中快速接入浮动气泡工具栏的编辑器并理解其底层由BalloonEditor、BalloonEditorUI、BalloonEditorUIView三层类协作的实现原理。Balloon Editor 是什么Balloon Editor 是 CKEditor 5 提供的六种开箱即用编辑器类型之一其余为 classic、inline、balloon block、decoupled/document、multi-root本包即其官方实现。它采用与 Inline Editor 类似的“内容就地编辑”理念但在工具栏形态上有本质区别Inline Editor浮动工具栏在编辑器获得焦点如点击时出现Balloon Editor浮动工具栏以气泡balloon的形式出现在当前选中内容附近当选中非空时最典型的场景是 Medium 等博客写作平台——选中一段文字后格式工具紧贴选区浮现实现真正的所见即所得、即选即用。在此基础上还衍生出Balloon Block Editor它本质上是 Balloon Editor 加上一个附在编辑内容区的块级工具栏按钮可跟随文档中的选区移动提供额外的块级编辑功能如段落/标题切换配置方式见 editor-types.md。本包在仓库中位于 packages/ckeditor5-editor-balloon版本号见 package.json当前为 48.5.0包内仅包含 4 个核心源码文件与对应测试、手动测试页面。安装与引入Balloon Editor 属于 CKEditor 5 的开源聚合包open-source aggregate package直接安装主包即可使用无需单独安装本包npm install ckeditor5然后从主包中按需导入编辑器类型与所需插件import { BalloonEditor, Essentials, Bold, Italic, Font, Paragraph } from ckeditor5;仓库内该包的 index.ts 确认了对外导出的全部符号为BalloonEditor、BalloonEditorUI、BalloonEditorUIView其中后两者属于 UI 内部类日常开发只需使用BalloonEditor及其静态方法create()。三种初始化方式源码级详解BalloonEditor.create()是创建实例的唯一入口其类型重载与实现均位于 ballooneditor.ts。从源码可以看到它支持三种初始化形态其中第一种为当前推荐用法后两种已标记deprecated但仍向后兼容。方式一基于已有 DOM 元素config 对象形式推荐将目标 DOM 元素放入配置的root.element中BalloonEditor .create( { root: { element: document.querySelector( #editor ) } } ) .then( editor { console.log( Editor was initialized, editor ); } ) .catch( err { console.error( err.stack ); } );此时元素原有的内容会作为编辑器初始数据元素本身成为可编辑区editable。从 ballooneditor.ts 可以看出源码会通过normalizeRootsConfig()将root归一化为标准的roots.main形态随后调用secureSourceElement()对该元素进行保护同一元素不允许被多个编辑器实例重复使用。方式二直接传入初始数据创建分离式编辑器也可以把初始 HTML 字符串直接作为参数传入BalloonEditor .create( pHello world!/p ) .then( editor { console.log( Editor was initialized, editor ); // 初始数据模式下编辑器 UI 元素是分离的需要手动挂载到 DOM document.body.appendChild( editor.ui.element ); } ) .catch( err { console.error( err.stack ); } );这种模式下不会绑定任何源 DOM 元素editor.sourceElement为undefined测试用例见 ballooneditor.js编辑器渲染出一个新元素必须通过editor.ui.element手动插入页面。适合客户端动态生成内容、初始化时 DOM 结构尚未就绪的场景。方式三DOM 元素 配置初始数据混合模式将源元素与root.initialData结合使用适用于“难以直接向源元素写入内容”的集成场景BalloonEditor .create( document.querySelector( #editor ), { root: { initialData: h2Initial data/h2pFoo bar./p } } ) .then( editor { console.log( Editor was initialized, editor ); } ) .catch( err { console.error( err.stack ); } );源码特别提示如果将初始数据同时传给第一个参数和配置项会抛出editor-create-initial-data-overspecified相关错误详见下文“常见错误与约束”一节。完全配置化config-only形态除上述三种签名外create()还支持只传配置对象的形态如create( { root: { initialData: pFoo/p } } )这是从测试用例与手动测试中可以确认的另一种写法详见 tests/ballooneditor.js。创建流程与生命周期从 ballooneditor.ts 的实现可以看到create()的完整调用链new this(...)构造编辑器实例构造函数中完成 roots 归一化、BalloonToolbar 注入、UI 视图创建await editor.initPlugins()初始化全部插件verifyRootElements( editor )校验根元素推迟到此时是因为插件可能在init()阶段才注册自定义 schema 元素见源码注释await editor.ui.init()初始化 UIawait editor.data.init( ...initialData )载入初始数据editor.fire( ready )触发ready事件并返回编辑器实例。销毁时调用editor.destroy()源码ballooneditor.ts会先缓存数据再销毁 UI 与引擎最后在配置了updateSourceElementOnDestroy: true时把最新内容回写到源元素。这与其它编辑器类型共享ElementApiMixin该 mixin 提供了updateSourceElement等方法见同文件第 32 行。源码架构三个类的分工BalloonEditor编辑器本体BalloonEditor 继承自ElementApiMixin(Editor)editorName为BalloonEditor。构造函数中值得关注的两个自动化行为自动注入 BalloonToolbar构造时将BalloonToolbar来自ckeditor/ckeditor5-ui追加进plugins数组因此你无需手动引入气泡工具栏插件配置转发balloonToolbar配置默认取toolbar的值this.config.define( balloonToolbar, this.config.get( toolbar ) )即顶层toolbar配置会自动成为气泡工具栏内容。这一行为在测试 ballooneditor.js 中得到验证。BalloonEditorUIUI 控制器BalloonEditorUI 继承自EditorUI其elementgetter 直接返回可编辑区元素view.editable.element这解释了为什么分离式编辑器只需把editor.ui.element追加到 DOM 即可。其init()的核心职责包括将 editable 的name设为编辑根名用于 ARIA 属性识别通过rootAcceptsBlocks()判断根元素是否为 inline rootisInlineRoot渲染视图、向编辑器注册可编辑元素将 editable 的isFocused与全局focusTracker绑定——这样即使焦点在气泡工具栏或下拉面板上可编辑区仍保持聚焦样式attachDomRoot()将可编辑元素接入引擎的编辑视图完成“UI 与引擎的对接”调用_initPlaceholder()处理占位符placeholder并初始化菜单栏menu bar。BalloonEditorUIViewUI 视图BalloonEditorUIView 继承自EditorUIView内部组合了InlineEditableUIView内联可编辑区视图与MenuBarView菜单栏视图。render()时把二者注册为子组件。这是 Balloon Editor 与 Classic/Decoupled 的本质差异所在它没有独立的包裹容器直接以可编辑区本身作为 UI 载体。root 配置体系详解Balloon Editor 的所有根配置统一归一到roots.main下支持以下子配置均有测试用例佐证配置项说明支持形式root.element可编辑区元素真实 DOM 元素、标签名字符串如h1、视图元素定义对象{ name: section, classes, styles, attributes }root.initialData编辑器初始数据HTML 字符串字符串root.placeholder空内容占位符提示字符串root.label可编辑区的aria-label无障碍标签字符串或{ main: ... }对象root.modelElement自定义模型根元素名需为 schema 中的 limit 元素字符串root.modelAttributes附加到模型根的属性键值对象element 的三种形态// 1. 真实 DOM 元素 root: { element: document.querySelector( #editor ) } // 2. 标签名字符串编辑器自动创建该标签的可编辑元素 root: { element: h1 } // 3. 视图元素定义对象可附带 class、style、任意属性 root: { element: { name: section, classes: [ foo, bar ], styles: { color: red }, attributes: { data-id: 123 } } }相关断言可在 tests/ballooneditor.js 中查到标签名会反映到视图根如viewRoot.name h1classes会叠加在编辑器自带类ck、ck-content之上styles对象优先于attributes.style字符串省略element时默认创建div可编辑区。无障碍标签aria-label未配置时默认值为Rich Text Editor. Editing area: main测试见 ballooneditor.js若源元素自带aria-label则保留该值配置label时则覆盖之。常见错误与约束以下错误码均来自测试断言可作为排查清单editor-source-element-already-used同一 DOM 元素被多个编辑器实例重复初始化editor-wrong-elementtextarea或input元素不能作为可编辑区含标签名形式的textarea/inputeditor-create-initial-data-overspecified/editor-create-root-initial-data-overspecified初始数据既作为第一个参数传入又在配置中声明editor-create-roots-with-main同时使用root与roots.main配置editor-create-legacy-initial-data-overspecified同时使用遗留的initialData与root/roots.main中的初始数据editor-create-root-element-overspecified既传源元素又在root.element中指定元素editor-create-attachto-ignoredconfig-only 形态下设置attachToBalloon Editor 不接受该配置editor-root-element-is-not-limitroot.modelElement指定的模型元素不是 schema 中的 limit 元素测试见 ballooneditor.js。此外config.initialData、config.placeholder、config.label等遗留legacy顶层配置会被自动归一化到roots.main.*以保证旧代码兼容测试见 ballooneditor.js。完整实战示例结合仓库中的 手动测试示例一个带完整功能的 Balloon Editor 初始化代码如下import { BalloonEditor, Essentials, Paragraph, Heading, Bold, Italic, Link, List, BlockQuote } from ckeditor5; BalloonEditor .create( { root: { element: document.querySelector( #editor ), placeholder: Type your content here... }, plugins: [ Essentials, Paragraph, Heading, Bold, Italic, Link, List, BlockQuote ], // toolbar 配置会自动转发为 balloonToolbar即气泡工具栏中的按钮 toolbar: [ heading, |, bold, italic, link, bulletedList, numberedList, blockQuote ] } ) .then( editor { console.log( Balloon editor ready, editor ); } ) .catch( err { console.error( err.stack ); } );仓库中还提供了多种手动测试页面可用于直观验证不同场景例如ballooneditor.manual.html —— 基础的气泡编辑器初始化与销毁演示ballooneditor-inline.manual.html —— 内联根inline root场景placeholder.manual.html —— 占位符配置演示memory.manual.html —— 内存/销毁流程演示。总结Balloon Editor 是 CKEditor 5 面向“选中即格式化”场景的官方编辑器类型其实现集中在 packages/ckeditor5-editor-balloon 这一轻量包内BalloonEditor负责装配与生命周期BalloonEditorUI负责可编辑区与引擎的桥接和占位符/菜单栏管理BalloonEditorUIView则以内联可编辑视图为载体承载全部 UI。通过create()的多种签名与丰富的root配置你可以灵活地将它嵌入博客、评论框、知识库等任何需要就地编辑的界面中。更多编辑器类型选型与对比可参考 Editor types在线演示入口见 Balloon editor example。【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表