- 前端
- UI组件
【免费下载链接】ckeditor4
The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.
导读
本文基于 CKEditor 4 官方仓库中的手动测试用例 iosbuttonkama.md,系统讲解工具栏按钮(Button)在 iOS 触屏设备上 hover 样式行为的历史缺陷(issue #4611)、CSS 修复原理(@media (hover: none)媒体查询)、Kama 皮肤三档按钮状态的配色体系,以及如何在 Bender 测试框架下按步骤执行手动验收、区分预期与意外结果。读完本文,你将掌握 CKEditor 4 工具栏按钮状态机与皮肤样式的对应关系,能够独立复现、验证并扩展移动端 hover 相关测试。
一、背景:触屏设备上的伪 hover 困境与 issue #4611
1.1 问题现象
在传统桌面端,:hover伪类由鼠标悬停触发,语义清晰。但在 iOS / Android 等触屏设备上,浏览器为了兼容桌面站点的交互,会在手指按下(touch)期间临时把元素视为:hover状态,导致 CKEditor 工具栏按钮在"按下的过程中"就提前显示 hover 背景色,而不是等到手指松开后才呈现。这种"按压即高亮"的行为会造成两个视觉问题:
- 按压期间就出现 hover 样式,与按钮点击后的反馈(toggled on 状态)混叠,用户难以区分"正在按"与"已经选中";
- 松开手指后,hover 样式应有的"闪现"(flash)反馈丢失,交互层次感被破坏。
该问题在 CHANGES.md 的 4.16.1 版本记录中被明确归类为缺陷修复:
#4611: [Android, iOS] Fixed: Incorrect hover styles for buttons in the toolbar on mobile devices.
1.2 修复思路:用hover: none区分设备能力
修复的核心手段是 CSS 媒体查询@media screen and ( hover: none )。该查询在设备不具备悬停能力(即无法用指针悬停、只能触摸)时命中,从而在移动端覆盖掉默认的:hover规则,同时保留并恢复:active规则,保证按压反馈仍然存在。
以 Kama 皮肤的工具栏样式 skins/kama/toolbar.css 为例,桌面端默认规则为:
a.cke_button_on:hover, a.cke_button_on:focus, a.cke_button_on:active { background-color: #86caff; } a.cke_button_off:hover, a.cke_button_off:focus, a.cke_button_off:active { background-color: #dff1ff; opacity: 1; } /* Disable hover styles on mobile devices (#4611). */ @media screen and ( hover: none ) { a.cke_button_off:hover { background: transparent; opacity: 0.7; } a.cke_button_on:hover { background-color: #a3d7ff; } /* We need to restore :active styles. */ a.cke_button_off:active { background-color: #dff1ff; opacity: 1; } a.cke_button_on:active { background-color: #86caff; } }可以清晰看到修复策略的两层含义:
- 在移动端把
:hover的样式还原为"未悬停"的默认外观:cke_button_off:hover变回透明背景、opacity: 0.7;cke_button_on:hover还原为 toggled on 的基准色#a3d7ff。这样手指按压期间按钮外观不会"提前高亮"。 - 显式恢复
:active样式:因为触屏设备上:hover与:active往往同时命中,若只禁用 hover,按压反馈也会丢失,因此注释明确写着 "We need to restore :active styles.",把#dff1ff(off 态按压)与#86caff(on 态按压)重新赋予:active。
同样的修复也应用到组合框(Rich Combo)组件上,见 skins/kama/richcombo.css 与 skins/moono/richcombo.css,说明该问题同时影响了工具栏按钮和下拉组合控件两类 UI 元素。
二、Kama 皮肤下工具栏按钮的三种视觉状态
手动测试文档以 Kama 皮肤为验收对象,用"浅蓝色 / 深蓝色 / 更深蓝色"描述三档状态。对应源码实现如下(见 skins/kama/toolbar.css):
| 状态 | CSS 选择器 | 背景色 | 含义 |
|---|---|---|---|
| 未激活(off) | a.cke_button_off | 透明背景,opacity: 0.7 | 功能可用但当前未生效 |
| 悬停 / 聚焦 / 按压(off 态) | a.cke_button_off:hover,:focus,:active | #dff1ff(浅蓝)且opacity: 1 | 用户正在与该按钮交互 |
| 已激活(on) | a.cke_button_on | #a3d7ff(深蓝) | 功能已生效(如正在输入粗体) |
| 已激活后的悬停 / 按压 | a.cke_button_on:hover,:focus,:active | #86caff(更深蓝) | 对已激活按钮的交互反馈 |
注释中也说明了类名语义:cke_button_on表示"与该按钮关联的功能处于激活状态,例如正在输入粗体或拼写检查已开启"(见 skins/kama/toolbar.css);cke_button_off表示"功能可用但当前未激活";另有cke_button_disabled(opacity: 0.3)表示功能不可用(如剪贴板为空时粘贴按钮置灰)。
因此文档中的三处描述一一对应:
- "hover 样式(light-blue background)" → off 态交互色
#dff1ff; - "toggled on 状态(darker blue background)" → 激活态
#a3d7ff; - "toggled on 按钮的 hover 样式(even darker blue background)" → 激活态交互色
#86caff。
三、按钮状态机的源码实现:toggled on 从何而来
"toggled on 状态"并非皮肤 CSS 凭空定义,而是由按钮 UI 组件的状态机驱动。核心实现在 plugins/button/plugin.js 的setState方法:
setState: function( state ) { if ( this._.state == state ) return false; this._.state = state; var element = CKEDITOR.document.getById( this._.id ); if ( element ) { element.setState( state, 'cke_button' ); element.setAttribute( 'aria-disabled', state == CKEDITOR.TRISTATE_DISABLED ); if ( this.isToggle && !this.hasArrow ) { element.setAttribute( 'aria-pressed', state === CKEDITOR.TRISTATE_ON ); } return true; } return false; }其中element.setState( state, 'cke_button' )负责把三态值映射为 CSS 类名(cke_button_on/cke_button_off/cke_button_disabled),从而切换背景色;同时同步aria-pressed与aria-disabled属性,保证无障碍语义与视觉状态一致。
按钮定义中的isToggle标志(默认false,见 plugins/button/plugin.js)决定按钮是否为"开关型"——只有开关型按钮在命令执行后才会在TRISTATE_ON与TRISTATE_OFF之间切换。例如basicstyles(粗体、斜体等)插件注册的命令即为开关型,这正是测试文档元数据中加载basicstyles插件的原因:用它来验证"点击后按钮进入 toggled on 状态"。
四、手动测试用例完整解读
4.1 Bender 元数据:测试的身份标识
文档头部是 Bender 手动测试(manual test)的元数据声明,见 iosbuttonkama.md:
@bender-tags: 4.16.1, 4611, bug @bender-ui: collapsed @bender-ckeditor-plugins: wysiwygarea, toolbar, basicstyles, language@bender-tags:标记该测试对应的版本(4.16.1)、issue 编号(4611)与类型(bug),便于在 Bender 结果面板中按标签筛选;@bender-ui: collapsed:测试页面 UI 折叠展示,仅保留编辑器主体,减少无关干扰;@bender-ckeditor-plugins:声明本用例需要加载的插件——wysiwygarea(iframe 版编辑区)、toolbar(工具栏渲染)、basicstyles(提供粗体/斜体等开关型命令,用于验证 toggled 状态)、language(提供语言选择命令)。
4.2 测试环境与页面结构
该目录下的手动测试共用同一个 HTML 模板template.html,页面包含两个编辑器:
#iframe-editor:基于<iframe>的经典编辑器(wysiwygarea);#div-editor:基于<div>的编辑区(通过extraPlugins: 'divarea'启用)。
模板脚本从 URL 路径中正则解析测试环境与皮肤((android|ios|desktop)(?:button|richcombo)(moono|kama)?),并用isIgnoredEnv()判断当前浏览器环境是否匹配;不匹配时调用bender.ignore()跳过测试。皮肤名缺省时回退为moono-lisa。因此,本文档(文件名含ios与kama)要求:在 iOS 设备(iPad / iPhone / iPod)上,使用 Kama 皮肤分别验证两个编辑器——这也是文档第 4 步要求"对第二个编辑器重复该过程"的原因。
4.3 四步验收流程(原文完整步骤)
步骤 1:检查 off 态按钮在长按期间与松开后的 hover 行为
对工具栏按钮长按并松开手指,观察:
- 预期结果:
- 手指按压期间不出现 hover 样式(浅蓝色背景);
- 松开手指的瞬间,hover 样式"闪现"(flash)一下,随后按钮进入 toggled on 状态。
- 意外结果:
- 按压期间就出现 hover 样式;
- 松开手指后没有出现 hover 样式的"闪现"。
步骤 2:检查点击后按钮的 toggled on 状态
- 预期结果:被点按的按钮处于 toggled on 状态(深蓝色背景
#a3d7ff)。 - 意外结果:按钮未进入 toggled on 状态。
步骤 3:检查 toggled on 按钮的 hover 行为
对已经处于 toggled on 状态的按钮再次长按并松开:
- 预期结果:
- 按压期间不出现 hover 样式(更深的蓝色
#86caff); - 松开手指瞬间 hover 样式"闪现"后,按钮回到 off 状态。
- 按压期间不出现 hover 样式(更深的蓝色
- 意外结果:
- 按压期间就出现 hover 样式;
- 松开后没有"闪现"。
步骤 4:对页面中的第二个编辑器(divarea 版)重复上述全部过程。
提示:所谓"闪现",正是移动端
:hover在手指离开后仍短暂保留一瞬的浏览器行为。修复后按压期间无 hover,松开瞬间 hover 出现又随状态切换而消失,形成一次极短的高亮反馈,让用户感知"按下 → 生效"的完整过程;同时由于修复把按压期间的高亮移除了,用户不会再误读"正在按下"为"已选中"。
4.4 该用例的验收意义
这份手动测试本质上是 issue #4611 修复的回归验收清单。四个步骤分别覆盖了:
- off 态按钮的交互反馈时序(按压中 vs 松开后);
- 点击后状态切换的正确性(toggled on);
- on 态按钮的交互反馈时序(按压中 vs 松开后);
- 两种编辑区实现(iframe 与 divarea)下行为的一致性。
只有全部步骤符合预期结果,才能认定hover: none修复在 iOS + Kama 组合下未引入回归。
五、测试矩阵:同一缺陷的多维度覆盖
tests/plugins/toolbar/manual/hover/目录下共有 18 个手动测试文件,构成一个完整的交叉矩阵,从三个维度覆盖 #4611:
- 设备环境:
android、ios、desktop(桌面端用于确保修复未破坏原有的 hover 行为); - UI 组件:
button(普通按钮)、richcombo(下拉组合框); - 皮肤:
kama、moono、moono-lisa(缺省)。
对应关系如下:
| 组件 / 环境 | Kama | Moono | Moono-Lisa |
|---|---|---|---|
| 按钮 - 桌面 | desktopbuttonkama.md | desktopbuttonmoono.md | desktopbutton.md |
| 按钮 - iOS | iosbuttonkama.md | iosbuttonmoono.md | iosbutton.md |
| 按钮 - Android | androidbuttonkama.md | androidbuttonmoono.md | androidbutton.md |
| 组合框 - 桌面 | desktoprichcombokama.md | desktoprichcombomoono.md | desktoprichcombo.md |
| 组合框 - iOS | iosrichcombokama.md | iosrichcombomoono.md | iosrichcombo.md |
| 组合框 - Android | androidrichcombokama.md | androidrichcombomoono.md | androidrichcombo.md |
桌面端用例(如 desktopbuttonkama.md)的预期结果与之相反——桌面端必须有hover 样式,这确保了hover: none媒体查询只在触屏设备生效,不误伤桌面鼠标体验。另外,Moono 皮肤同样包含@media (hover: none)修复块(见 skins/moono/toolbar.css),说明该修复是皮肤层面的通用策略,而非 Kama 独有。
六、如何运行该手动测试
该用例属于 Bender 手动测试(manual test)体系,需要通过 Bender 测试服务器打开页面,由测试人员在真实设备上按步骤执行。项目测试基础设施配置见 bender.js:
- 测试框架为
yui(framework: 'yui'); - 已加载的 Bender 插件包括
benderjs-coverage、benderjs-yui、benderjs-sinon、benderjs-jquery、tests/_benderjs/ckeditor与benderjs-yui-beautified; - 测试分组中
'Plugins'组以tests/为基准路径、匹配plugins/**,因此tests/plugins/toolbar/manual/下的用例会被收录(见 bender.js)。
运行步骤(面向仓库查看与测试执行者):
- 安装依赖:
npm install(Bender 相关依赖见 package.json 的 devDependencies); - 启动 Bender 服务并运行手动测试模式(对应
bender run配合--manual或手动测试入口,具体以 benderjs 文档为准),随后在浏览器中打开 Bender 手动测试列表; - 在iOS 真机或模拟器(iPad / iPhone / iPod)上打开本用例页面;
- 页面会自动加载两个编辑器(iframe 版与 divarea 版)并应用 Kama 皮肤(文件名含
kama);若当前访问设备并非 iOS,模板脚本会调用bender.ignore()跳过本用例; - 按 4.3 节的四步流程逐项操作,在 Bender 面板中勾选"通过 / 失败",将实际行为与预期结果比对。
需要特别说明的适用前提:本用例必须在 iOS 环境 + Kama 皮肤下执行才有效,其他设备/皮肤组合应选择矩阵中对应的其他用例;hover: none媒体查询的生效与否同时取决于浏览器对 Media Queries Level 4 悬停特性的支持程度。
七、结语:一条缺陷修复的完整闭环
从 issue #4611 出发,CKEditor 4 在皮肤层用@media screen and ( hover: none )精准区分了"能悬停的桌面指针"与"只能触摸的移动设备",在移动端移除按压期间的伪 hover 高亮、保留按压(:active)反馈与松开瞬间的 hover 闪现;在测试层用tests/plugins/toolbar/manual/hover/下 18 个用例组成"设备 × 组件 × 皮肤"的回归矩阵,其中 iosbuttonkama.md 负责 iOS + Kama + 按钮组合的四步验收。理解了这层 CSS 策略与测试矩阵,你不仅能在 CKEditor 4 上复现并验证该修复,也能把同样的"hover 能力检测 + 移动端去伪悬停 + 恢复 active"方法论迁移到自己的富文本编辑器或任意 Web 组件库中。
- 前端
- UI组件
【免费下载链接】ckeditor4
The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.
相关推荐
CKEditor 4 Moono 皮肤 iOS 工具栏按钮 Hover 样式手动测试指南(4611)
CKEditor 4 Moono 皮肤 iOS 工具栏按钮 Hover 样式手动测试指南( 4611) 导读 本文围绕仓库中的 Bender 手动测试用例 te
前端UI组件CKEditor 4 工具栏按钮 Android 移动端 Hover 样式回归测试:解读 4611 修复与 Bender 手工测试流程
CKEditor 4 工具栏按钮 Android 移动端 Hover 样式回归测试:解读 4611 修复与 Bender 手工测试流程 本文围绕 CKEdito
前端UI组件CKEditor 4 移动端工具栏 Rich Combo Hover 样式问题验证指南:iOS 手动测试与 4611 修复原理
CKEditor 4 移动端工具栏 Rich Combo Hover 样式问题验证指南:iOS 手动测试与 4611 修复原理 本文以 CKEditor 4 仓
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考