fix(练习): 修复答案隐藏后焦点恢复逻辑

feat(知识领域): 添加敏捷裁剪因素数据

- 修复答案隐藏后聚焦到第一个空输入框而非第一个输入框
- 添加 restoreFocus 辅助函数统一处理焦点恢复
- 更新知识领域裁剪因素数据

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
ittoview
2026-03-01 16:57:16 +00:00
parent 8f96865ebf
commit 713c11b382
2 changed files with 45 additions and 27 deletions

View File

@@ -52,7 +52,29 @@
"order": 2,
"color": "#8B5CF6",
"description": "确保项目包含且只包含成功完成项目所需的全部工作",
"processCount": 6
"processCount": 6,
"tailoringFactors": [
{
"title": "知识和需求管理",
"description": "项目经理应建立哪些指南?为了在未来项目中重复使用需求,组织是否拥有正式或非正式的知识和需求管理体系?"
},
{
"title": "确认和控制",
"description": "组织是否有正式或非正式的与确认和控制相关政策、程序和指南?"
},
{
"title": "开发方法",
"description": "组织是否采用敏捷方法管理项目?开发方法属于迭代型还是增量型?是否采用预测型方法?混合型方法是否有效?"
},
{
"title": "需求的稳定性",
"description": "项目中是否存在需求不稳定的领域?是否有必要采用精益、敏捷或其他适应型技术来处理不稳定的需求,直至需求稳定且定义明确?"
},
{
"title": "治理",
"description": "组织是否拥有正式或非正式的审计和治理政策、程序和指南?"
}
]
},
{
"id": "KA03",

View File

@@ -90,6 +90,23 @@ export default function ProcessPracticePage() {
}
}, [answeredCells, currentCellId])
// 恢复焦点到第一个空输入框
const restoreFocus = useCallback(() => {
setTimeout(() => {
const inputs = document.querySelectorAll('.practice-input-area input')
const firstEmptyInput = Array.from(inputs).find(
(input) => !(input as HTMLInputElement).value
) as HTMLInputElement
if (firstEmptyInput) {
firstEmptyInput.focus()
} else {
// 如果所有输入框都有值,聚焦到第一个
(inputs[0] as HTMLInputElement)?.focus()
}
}, 100)
}, [])
// 切换到指定格子
const switchToCell = useCallback(
(cell: CellInfo) => {
@@ -251,16 +268,9 @@ export default function ProcessPracticePage() {
setShowAnswerForCell(null)
setInputLocked(false)
announceToScreenReader('答案已隐藏')
// 恢复焦点到第一个输入框
setTimeout(() => {
const firstInput = document.querySelector(
'.practice-input-area input'
) as HTMLInputElement
firstInput?.focus()
}, 100)
restoreFocus()
}
}, [showAnswerForCell])
}, [showAnswerForCell, restoreFocus])
// 自动过期检查
useEffect(() => {
@@ -270,14 +280,7 @@ export default function ProcessPracticePage() {
if (remainingTime <= 0) {
setShowAnswerForCell(null)
setInputLocked(false)
// 恢复焦点
setTimeout(() => {
const firstInput = document.querySelector(
'.practice-input-area input'
) as HTMLInputElement
firstInput?.focus()
}, 100)
restoreFocus()
return
}
@@ -285,18 +288,11 @@ export default function ProcessPracticePage() {
setShowAnswerForCell(null)
setInputLocked(false)
announceToScreenReader('答案已自动隐藏')
// 恢复焦点
setTimeout(() => {
const firstInput = document.querySelector(
'.practice-input-area input'
) as HTMLInputElement
firstInput?.focus()
}, 100)
restoreFocus()
}, remainingTime)
return () => clearTimeout(timer)
}, [showAnswerForCell])
}, [showAnswerForCell, restoreFocus])
// 点击格子切换(允许回顾已答对的格子)
const handleCellClick = useCallback(