CKEditor 4 floatpanel 浮层面板:窗口缩放与移动端软键盘场景下的定位行为验证指南

📅 发布时间:2026/10/16 5:40:20
CKEditor 4 floatpanel 浮层面板:窗口缩放与移动端软键盘场景下的定位行为验证指南
前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载导读本文围绕 CKEditor 4 中 floatpanel浮层面板组件在窗口尺寸变化与移动端软键盘弹出/收起两种场景下的定位与显示行为展开。floatpanel 是 CKEditor 4 工具栏下拉框Paragraph Format、Font、Color 等与右键菜单的底层承载组件其定位正确性直接影响编辑器的日常可用性。阅读本文后你将理解 floatpanel 的定位原理与reposition()机制掌握如何通过 Bender 手动测试用例验证面板在移动设备软键盘、浏览器窗口缩放下的表现并能对照自动化测试与源码定位同类回归问题。本文的验证要点以仓库中的手动测试说明 tests/plugins/floatpanel/manual/resize.md 为骨架结合 floatpanel 插件源码、Bender 自动化测试与格式下拉框format 插件实现展开。一、floatpanel几乎所有下拉 UI 的底层载体1.1 什么是 floatpanelfloatpanel 是 CKEditor 4 中的一个 UI 基础组件用于承载那些悬浮在文档上方、不占据正常文档流的面板内容。插件声明极其精简// plugins/floatpanel/plugin.js CKEDITOR.plugins.add( floatpanel, { requires: panel } );它本身不渲染任何 UI而是依赖panel插件提供的面板渲染能力对外暴露CKEDITOR.ui.floatPanel类并在构造时强制将面板内容放入 iframedefinition.forceIFrame 1见 plugins/floatpanel/plugin.js从而隔离宿主页面样式对面板内容的干扰。从源码注释可以确认它的使用范围It is reused by rich combos, color combos, menus, etc. and it renders its content using CKEDITOR.ui.panel.也就是说富下拉框rich combo、颜色下拉框、菜单等 UI 全部复用 floatpanel。1.2 谁在用它以 Paragraph Format 为例本文手动测试的主角是工具栏上的Paragraph Format段落格式下拉框。它由format插件通过richcombo注册// plugins/format/plugin.js init: function( editor ) { ... editor.ui.addRichCombo( Format, { label: lang.label, title: lang.panelTitle, toolbar: styles,20, ... panel: { css: [ CKEDITOR.skin.getPath( editor ) ].concat( config.contentsCss ), multiSelect: false, attributes: { aria-label: lang.panelTitle } }, ... } ); }而richcombo插件在声明依赖时直接指定了floatpanel// plugins/richcombo/plugin.js CKEDITOR.plugins.add( richcombo, { requires: floatpanel,listblock,button, ... });在createPanel()中richcombo 会实例化一个CKEDITOR.ui.floatPanel并注册列表块plugins/richcombo/plugin.jsvar panel new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ), list panel.addListBlock( this.id, panelBlockDefinition );因此Paragraph Format 下拉框展开后其视觉呈现与定位逻辑完全由 floatpanel 负责——这正是本测试用例要验证的对象。二、手动测试用例全解resize 场景2.1 测试文件与其元数据本用例位于tests/plugins/floatpanel/manual/目录由一对文件组成操作说明tests/plugins/floatpanel/manual/resize.md测试页面tests/plugins/floatpanel/manual/resize.htmlresize.md头部是 Bender 手动测试的元数据声明bender-tags: bug, 4.5.4, trac11724 bender-ui: collapsed bender-include: ../../embedbase/_helpers/tools.js bender-ckeditor-plugins: wysiwygarea,sourcearea,htmlwriter,entities,toolbar,elementspath,undo,clipboard,format,basicstyles,font,autolink,autoembed,link逐条解读指令含义bender-tags: bug, 4.5.4, trac11724标注该用例属于 bug 回归测试关联 4.5.4 版本中修复的 ticket #11724bender-ui: collapsed以折叠 UI 模式加载测试页面仅显示编辑器本体bender-include: ../../embedbase/_helpers/tools.js引入 embedbase 插件的测试辅助工具 tests/plugins/embedbase/_helpers/tools.jsbender-ckeditor-plugins: ...声明测试页启用的插件集合其中format提供 Paragraph Format 下拉框、richcombo经 format 间接依赖提供下拉框 UI 载体测试页面本体极其简单——一个 80% 宽度的居中容器内放置经典编辑器实例!-- tests/plugins/floatpanel/manual/resize.html -- div stylewidth: 80%; margin: 0 auto textarea cols80 idclassic nameclassic rows10 pTest/p /textarea /div script CKEDITOR.replace( classic ); /script2.2 移动设备验证步骤原文档针对移动端给出如下操作序列点击编辑区让系统软键盘弹出软件键盘可见点击工具栏上的 Paragraph Format 下拉框展开样式列表预期结果软键盘应自动收起且下拉框保持可见、位置正确。这条路径背后对应着一个真实的移动端 bugticket #11724。软键盘的弹出会改变浏览器视口高度触发window.resize事件而旧实现中 floatpanel 监听窗口 resize 后直接执行hide()导致在 Android / iOS 上下拉框一打开就消失。修复后窗口 resize 不再无条件隐藏面板而是触发重定位见下文第三节源码分析。2.3 其他设备桌面验证步骤原文档针对桌面浏览器给出另一组操作序列打开 Paragraph Format 下拉框检查其初始定位是否正确应紧贴下拉按钮、完整显示在视口内缩放浏览器窗口改变窗口尺寸预期结果下拉框应要么被隐藏要么被正确重定位不允许出现面板悬在半空、与触发按钮错位或面板被裁切的情况。注意要么隐藏、要么重定位是 4.5.4 修复后明确的两种合法结果——这与源码中hide()与reposition()两条路径并存的设计完全一致详见下文。2.4 判定标准小结设备类型触发操作期望结果移动设备点编辑区 → 软键盘弹出 → 点 Paragraph Format软键盘收起下拉框可见且定位正确桌面浏览器打开 Paragraph Format → 缩放窗口面板隐藏或正确重定位不错位、不裁切三、源码级原理4.5.4 的修复如何生效3.1 定位计算showBlock 的四个角floatpanel 的定位在showBlock()中完成plugins/floatpanel/plugin.js。它根据corner参数决定面板与触发元素的对齐方式LTR从左到右编辑器下1左上、2右上、3右下、4左下RTL从右到左编辑器下1右上、2左上、3左下、4右下。同时支持offsetX、offsetY微调偏移。定位完成后还有一段智能适配视口的逻辑plugins/floatpanel/plugin.js通过getBoundingClientRect()与getViewPaneSize()比较面板矩形与视口尺寸当右侧空间不足时向左翻转、下方空间不足时向上翻转确保面板完整落在视口内——这正是桌面步骤 2初始定位正确、不被裁切的实现保障。3.2 两类事件监听hide 与 repositionfloatPanel 构造函数中注册了如下事件plugins/floatpanel/plugin.jseditor.on( mode, hide ); editor.on( resize, hide ); // When resize of the window is triggered floatpanel should be repositioned according to new dimensions. // https://dev.ckeditor.com/ticket/11724. Fixes issue with undesired panel hiding on Android and iOS. doc.getWindow().on( resize, function() { this.reposition(); }, this );编辑器resize事件 → hide编辑器本体尺寸变化如用户拖动编辑器边框时直接隐藏面板避免面板与编辑器错位窗口resize事件 → reposition浏览器窗口尺寸变化包括移动端软键盘弹出导致的视口变化时调用reposition()重新摆放面板而不是隐藏。源码注释明确写到When resize of the window is triggered floatpanel should be repositioned according to new dimensions. Fixes issue with undesired panel hiding on Android and iOS.——这正是 ticket #11724 的修复内容与本文手动测试用例的trac11724标签一一对应。3.3 reposition 的实现完整重放 showBlockreposition()plugins/floatpanel/plugin.js是 4.5.4 新增的 API/** * Repositions the panel with the same parameters that were used in the last {link #showBlock} call. * * since 4.5.4 */ reposition: function() { var blockParams this._.showBlockParams; if ( this.visible this._.showBlockParams ) { this.hide(); this.showBlock.apply( this, blockParams ); } }其设计要点showBlock()在每次展示时会把入参快照保存到this._.showBlockParams见 plugins/floatpanel/plugin.jsreposition()仅在面板可见this.visible且存在快照时生效先隐藏再以完全相同的一组参数重新执行showBlock()由于窗口尺寸已经变化showBlock()内部的视口适配逻辑会依据新尺寸重新计算翻转方向与坐标从而把面板搬到正确位置。因此桌面场景下缩放窗口时如果面板仍可见它会带着一致的触发参数被重新摆放——而不是停留在旧坐标上。3.4 为什么移动端软键盘收起能保住面板移动端软键盘弹出时浏览器会收缩视口高度触发窗口 resize此时面板通过reposition()被重新计算位置不会被直接隐藏。同时showBlock()中还针对 iOS 做了 blur 时序保护plugins/floatpanel/plugin.jsiframe blur 后不立即隐藏而是用CKEDITOR.tools.setTimeout( doHide, 0, this )延迟执行并监听touchstart/touchend取消误触发——这样点编辑区弹出键盘 → 再点下拉框的连续操作不会因为焦点抖动把面板关掉。注意bender-tags: ... 4.5.4, trac11724表明该用例是为验证 4.5.4 的修复而设计的手动回归用例预期行为以 4.5.4 及以后版本的实现为准。四、如何运行本手动测试Bender 是 CKEditor 4 的测试运行器其配置见 bender.js。手动测试需要指定接受手动测试的浏览器manualBrowsers配置项bender.js并且测试服务器需要以 HTTPS 提供服务privateKey/certificate配置指向 tests/_benderjs/ssl/key.pem 与 tests/_benderjs/ssl/cert.pem。典型运行方式在仓库根目录安装并启动 Bender 测试服务器将浏览器加入manualBrowsers列表本用例需要真机或模拟器上的移动浏览器以及一台桌面浏览器打开 Bender 手动测试面板定位到plugins/floatpanel→resize用例分别按上文第二节移动设备与其他设备两组步骤操作并核对预期结果若面板在软键盘弹出后消失、或在窗口缩放后错位/被裁切即为回归应关联 ticket #11724 排查。bender-ui: collapsed意味着测试页会以折叠 UI 呈现便于聚焦编辑器本体bender-include引入的 tests/plugins/embedbase/_helpers/tools.js 为该页面提供辅助工具函数同时它也是 autoembed 相关测试的共用助手。五、配套自动化测试把行为固化为断言除了手动用例floatpanel 还配有 Bender 自动化测试 tests/plugins/floatpanel/floatpanel.js其中test panel reposition on window resize与手动用例直接呼应// 模拟 window resize 事件 var e document.createEvent( HTMLEvents ); e.initEvent( resize, true, false ); document.body.dispatchEvent( e ); assert.isTrue( showBlockSpy.calledTwice, panel.showBlock should be called twice ); assert.isTrue( repositionSpy.calledOnce, panel.reposition should be called once ); // 检查第二次 showBlock 使用了与第一次完全相同的参数 args showBlockSpy.firstCall.args; assert.isTrue( showBlockSpy.secondCall.calledWith( args[0], args[1], args[2] ), Second showBlock() call should use same arguments as first call. );这段测试用sinon.spy分别监听showBlock与reposition断言窗口 resize 触发后reposition()恰好被调用一次showBlock()被调用两次首次打开 reposition 内部重放第二次showBlock()的参数与第一次完全一致——验证了reposition()用相同参数重放的实现约定。同文件还覆盖了面板的打开/隐藏、mode切换时隐藏、编辑器resize时隐藏、第二个面板在编辑器 resize 时被关闭ticket #9800等行为共同构成 floatpanel 生命周期与定位行为的回归防线。手动用例与自动化用例互补自动化用例锁定事件→调用的契约手动用例则验证真实设备上的视觉结果软键盘交互、视口适配。六、版本与历史背景4.5.4修复 ticket #11724——触屏设备上下拉框经常在打开后立即消失。核心改动即在窗口 resize 时调用reposition()而非隐藏并在插件源码中保留了明确的注释说明plugins/floatpanel/plugin.js。4.5.8同目录下另一手动用例 tests/plugins/floatpanel/manual/rendering.md标签4.5.8, trac13756验证列表项内右键菜单的渲染布局不被裁切与本文用例同属 floatpanel 布局正确性的回归矩阵。更早的 4.x 版本中ticket #9800Hide float panel when resizing the window确立了窗口 resize 时面板应隐藏或重定位的行为边界见 CHANGES.md#11724 则进一步区分了移动端软键盘这一特殊 resize 来源。这些历史 ticket 号trac11724、trac9800、trac13756均出现在测试元数据与 CHANGES.md 的 Fixed Issues 列表中可作为回归排查时的检索关键词。七、结论与实践要点floatpanel 是 CKEditor 4 下拉 UI 的公共底座Paragraph Format、Font、颜色等 richcombo 下拉框及菜单都由它渲染与定位依赖链format → richcombo → floatpanel → panel。窗口 resize 与编辑器 resize 是两条不同的处理路径前者触发reposition()重定位4.5.4 起后者触发hide()隐藏二者不可混淆。移动端软键盘场景的关键软键盘弹出引起的视口变化不应导致下拉框消失验证时重点观察软键盘收起 面板保持可见且定位正确。桌面缩放场景的验收标准缩放窗口后面板要么被隐藏要么被正确重定位不得出现错位或裁切。回归防线完整手动用例tests/plugins/floatpanel/manual/resize.md验证真实设备表现自动化用例tests/plugins/floatpanel/floatpanel.js锁定reposition()的行为契约配合 CHANGES.md 中的 ticket 记录可快速定位同类问题。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐CKEditor 4 Balloon Toolbar 窗口缩放重定位机制与手动测试指南CKEditor 4 Balloon Toolbar 窗口缩放重定位机制与手动测试指南 本篇技术指南围绕 CKEditor 4 balloontoolbar 前端UI组件CKEditor 4 Emoji 自动补全面板视口定位验证指南从 Bender 手动测试到源码级定位原理CKEditor 4 Emoji 自动补全面板视口定位验证指南从 Bender 手动测试到源码级定位原理 本文面向 CKEditor 4 的插件开发者与测试工前端UI组件CKEditor 4 Mentions 面板视口内智能定位手动测试用例、源码原理与回归验证CKEditor 4 Mentions 面板视口内智能定位手动测试用例、源码原理与回归验证 CKEditor 4 的 Mentions提及插件让用户通过输前端UI组件上一篇5分钟掌握跨平台资源下载神器从视频号到小红书的一站式解决方案下一篇突破标注精度瓶颈Xtreme1测量工具深度解析与效能优化指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考