优化选择器操作逻辑,通用模式代码单独封装
This commit is contained in:
@@ -47,3 +47,57 @@ src/
|
||||
- fillPickerField中的DOM差异对比弹出层检测是核心机制,不要简化或删除
|
||||
- detectPickerField的方式3(主动点击检测DOM变化)是自建组件选择器识别的关键,不要删除
|
||||
- UI_LIB_PICKER_CONFIGS里不要加容易误匹配的配置(如之前Beisen Phoenix被误匹配到新东方自建网站)
|
||||
|
||||
## 填充操作核心规范
|
||||
|
||||
- **所有字段填充必须走 `fillMatchedField` 统一入口**,禁止在外部自行编写填充逻辑
|
||||
- **选择器类型字段(下拉、日期、月份、级联等)绝对不能用 `forceSetValue` 直接写值**,这类 input 通常是受控组件,直接写值无效
|
||||
- **选择器类型检测必须走 `detectPickerField` 统一入口**(pickerDetector.ts),禁止在外部自行判断字段是否为选择器
|
||||
- detectPickerField 内部已封装三种检测方式:UI组件库类名匹配 → 提示文字检测 → 主动点击DOM差异对比
|
||||
- 不要自行通过 readonly、class 等属性简单判断是否为选择器,这样会漏判
|
||||
- 时间字段(开始时间/结束时间/起止时间)如果没有找到 `placeholder="年"/"月"` 的下拉输入框,必须标记 `isPicker=true` 走 `fillMatchedField` → `fillPickerField` → `fillDatePicker` → `tryFillMonthPanel` 已封装的完整链路
|
||||
- **禁止在新增代码中自行编写选择器展开、月份点击、日期导航等操作逻辑**,必须先查看项目中已封装的方法并直接引用:
|
||||
- 选择器类型检测 → `pickerDetector.ts`(detectPickerField)
|
||||
- 日期/月份选择器操作 → `datePicker.ts`(fillDatePicker / tryFillMonthPanel / navigateToYearMonth / clickDayCell)
|
||||
- 下拉选项匹配与点击 → `pickerFill.ts`(clickBestOptionInDropdown / findAndClickOptionInVisiblePopups)
|
||||
- 选择器展开与DOM差异检测 → `autofill.ts` 中的 `fillPickerField`
|
||||
- 单选按钮点击 → `autofill.ts` 中的 `fillRadioField`
|
||||
- 搜索型选择器 → `autofill.ts` 中的 `fillSearchPickerField`
|
||||
- 年月下拉选择器 → `autofill.ts` 中的 `fillYearMonthPicker`
|
||||
- `datePicker.ts` 中的按钮探测逻辑(detectNavButtons:逐个点击观察年月变化)是通用日期选择器适配的核心,不要简化或删除
|
||||
|
||||
## 经历段落定位核心规范
|
||||
|
||||
- `experienceSection.ts` 中的段落容器定位逻辑(DOM 差异对比 + 特征重建)是5大经历区域填写的核心,**不可擅自修改或简化**
|
||||
- 核心原理:
|
||||
1. 点击添加按钮前后,用 `snapshotElementsInRange` / `diffSnapshots` / `findTopLevelNewElements`(dom.ts)对比 DOM 快照差异
|
||||
2. 找到新增的顶层容器(一段经历的完整 DOM),记住它的 tag + className 前缀作为段容器特征
|
||||
3. 同时保存新增段容器的 DOM 引用(`lastNewContainerEl`)
|
||||
4. 所有段添加完后,从 `lastNewContainerEl.parentElement` 出发,在父级 children 中匹配所有同特征兄弟容器
|
||||
5. 按 DOM 顺序重建 `segmentRanges` 数组,确保每段经历的 containerElement 精确对应
|
||||
- **禁止**用 input 差集(`beforeInputs`)来定位段容器——React 重渲染会导致原始段的 input 节点被重建,差集不可靠
|
||||
- **禁止**依赖 `titleElement` 存活状态来做重建——React 重渲染可能使 titleElement 脱离 DOM
|
||||
- 对于初始有1段且不需要添加的经历:走 `detectFirstSegment` 的 fallback 逻辑(无同级兄弟时 containerElement 可能为 null,`matchFormFieldsInRange` 有 fallback 用 startElement/endElement 范围搜索)
|
||||
|
||||
## 下拉选择器弹出层搜索核心规范
|
||||
|
||||
- **弹出层检测不依赖任何固定类名**,全部走 DOM 差异对比(点击前后全页面快照对比新增/新可见元素)
|
||||
- **禁止使用 POPUP_SELECTORS 或任何固定 CSS 选择器来检测弹出层**,必须走全页面可见性差异对比(`offsetHeight > 0 && offsetWidth > 0`)
|
||||
- **pickerDetector.ts 方式3(主动点击检测)的核心约束**:
|
||||
- 检测到弹出层后 **禁止关闭弹出层**(不调用 dismissPopup)
|
||||
- 将弹出层 DOM 引用保存到 `field.pickerDropdownElement`
|
||||
- fillPickerField 步骤0 直接在已有弹出层内搜索,避免二次点击触发 toggle 关闭
|
||||
- 弹出层由用户选择后自动关闭,无需手动干预
|
||||
- **选项搜索必须限定在检测到的弹出层元素内**,禁止全页面搜:
|
||||
- `findAndClickOptionInVisiblePopups(fillValue, labelText, popupEl?)` 没有 `popupEl` 时直接返回 false,不做全页面搜
|
||||
- `fillPickerField` 步骤0 用 `field.pickerDropdownElement`(pickerDetector 保存的引用)在弹出层内搜索
|
||||
- `fillPickerField` 步骤4 在 DOM 差异检测到的 `dropdownEl` 内搜索
|
||||
- `fillSearchPickerField` 轮询检测到的 `newPopupEl` 传给 `clickBestOptionInDropdown` 和 `findAndClickOptionInVisiblePopups`
|
||||
- **fillPickerField 步骤0**:pickerDetector 可能已展开弹出层(toggle 冲突问题),所以在步骤1之前先尝试在当前页面搜索匹配选项,避免二次点击关闭弹出层。**不可删除此步骤**
|
||||
- **isAsyncDropdown 字段的特殊处理**(FormLabelItem.isAsyncDropdown = true):
|
||||
- 接口异步下拉字段(如学校、专业)输入值后需轮询等待接口返回数据(最多3秒)
|
||||
- 弹出层检测阈值为 ≥1 个可见子元素(普通字段为 ≥2)
|
||||
- 检测到弹出层后优先用 `clickBestOptionInDropdown(newPopupEl)` 在弹出层内直接做文字匹配
|
||||
- 禁止对 isAsyncDropdown 字段走 `tryClickDropdownListItem` 全页面搜(选项数可能为1,全页面搜会被其他同规格元素干扰)
|
||||
- `pickerFill.ts` 中 `groupBySpec` / `findVisibleListGroups` 的同规格标签组阈值为 ≥2(不可改回 ≥3,否则只有2个选项的下拉列表会漏匹配)
|
||||
- `clickBestOptionInDropdown` 是在指定弹出层 DOM 内递归搜所有可见叶子文字节点做模糊匹配的核心方法,**不可简化其递归逻辑**
|
||||
|
||||
Reference in New Issue
Block a user