fix(练习): 修复答案隐藏后焦点恢复逻辑
feat(知识领域): 添加敏捷裁剪因素数据 - 修复答案隐藏后聚焦到第一个空输入框而非第一个输入框 - 添加 restoreFocus 辅助函数统一处理焦点恢复 - 更新知识领域裁剪因素数据 via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user