Appearance
主面板与设置面板单选点击无效/多选的原因与修复总结
现象复盘
- 在导入模式导入行为导出路径等单选组中,点击切换后高亮不更新或出现两个选项同时高亮(看起来像多选)。
- 控制台可见日志高级导入模式已更改为: direct/custom_folder,但界面仍显示上一次选择;同时导出模式日志保持为
custom_folder,与导入模式切换无关。
根因分析(并列因素叠加)
- 事件顺序导致选择被回滚
- 导入模式的
change处理在早期实现中先调用updateSettingsUI(),该方法根据旧的settings.mode重绘 UI。 - 因为未先保存新选择到设置,重绘会把刚刚点击的单选按钮恢复为旧值,导致点击无效。
- 样式刷新触发不足
- 多数单选组点击后并未统一调用样式刷新,
label上的.checked或.checked-export类没有即时切换; - 新旧标签的类未被清理,视觉上出现两个选项同时高亮(多选)。
- 样式计算来源不一致(设置值强制覆盖 DOM)
updateModeButtonStyles()曾尝试用当前设置值去强制radio.checked,其与用户点击后的 DOM 状态产生竞争;- 在设置未及时更新的情况下,样式函数会覆盖用户刚选中的项,引发显示异常。
- 快速设置与高级设置的同步耦合不健壮
- 仅在
quickSettingsInitialized为真时才把导入模式写入设置;在扩展面板复杂初始化阶段,该标志可能为假,导致主/设置面板状态不同步。
- CSS 机制及 CEP 兼容性
- 由于 CEP 环境不可靠支持
:has,本项目用.checked/.checked-export类模拟选中态; - 一旦事件未触发样式更新或类没有被正确增删,就会出现看起来多选或高亮不更新。
触发链路(典型一次点击)
- 用户点击导入模式”。
- 旧逻辑:未立即
updateField('mode', ...);直接updateSettingsUI()依据旧设置重绘 新选择被回滚。 - 同时样式函数未被统一调用,导致旧
label的选中类仍存在,新label也显示选中,形成视觉多选。
修复措施(当前已生效)
- 事件顺序调整:在导入模式
change中,先this.settingsManager.updateField('mode', radio.value, false),再调用updateSettingsUI()与updateModeButtonStyles(),避免重绘回滚。 - 简化样式刷新策略:
updateModeButtonStyles()仅基于 DOM 的input[type="radio"].checked来增删.checked/.checked-export,不再用设置值强制覆盖radio.checked。 - 增加通用监听器:对
import-mode、quick-import-mode、advanced-import-behavior、import-behavior、timeline-placement、export-mode的change统一触发样式刷新,保证即时高亮与互斥视觉。 - 保持导出模式独立:导出模式日志与导入模式无关,维持其原本的独立保存与高亮逻辑,避免误关联导致混乱。
验证方法
- 在设置面板逐一点击上述单选组,确认:
- 只存在一个选项高亮(蓝/橙/紫),视觉互斥;
- 切换后立即生效,关闭再打开面板仍保持最后选择;
- 控制台日志与视觉一致。
相关代码位置
index.html:单选结构与类(导入/导入行为/导出) 约 42884365 行;选中态 CSS 约 28102880 行。js/main.js:- 导入模式
change处理约 63656505 行(已改为先保存再刷新)。 - 通用
change监听器约 65956755 行(统一触发样式刷新)。 updateModeButtonStyles()约 84588635 行(仅依据 DOM 选中状态增删类)。
- 导入模式
避坑与建议
- UI 刷新前务必先更新底层设置,避免按旧设置重绘。
- 视觉选中态应源于真实 DOM 状态,避免逻辑层强制覆盖。
- 在 CEP/旧浏览器场景下,避免依赖
:has,用类驱动样式并确保每次交互都增删到位。 - 快速设置与高级设置的双向同步尽量解耦事件与保存顺序,保证一致性。
变更摘要
- 调整导入模式
change的保存顺序。 - 重写
updateModeButtonStyles()为 DOM 驱动。 - 增加通用单选变化监听,统一触发样式刷新。