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,
|
"order": 2,
|
||||||
"color": "#8B5CF6",
|
"color": "#8B5CF6",
|
||||||
"description": "确保项目包含且只包含成功完成项目所需的全部工作",
|
"description": "确保项目包含且只包含成功完成项目所需的全部工作",
|
||||||
"processCount": 6
|
"processCount": 6,
|
||||||
|
"tailoringFactors": [
|
||||||
|
{
|
||||||
|
"title": "知识和需求管理",
|
||||||
|
"description": "项目经理应建立哪些指南?为了在未来项目中重复使用需求,组织是否拥有正式或非正式的知识和需求管理体系?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "确认和控制",
|
||||||
|
"description": "组织是否有正式或非正式的与确认和控制相关政策、程序和指南?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "开发方法",
|
||||||
|
"description": "组织是否采用敏捷方法管理项目?开发方法属于迭代型还是增量型?是否采用预测型方法?混合型方法是否有效?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "需求的稳定性",
|
||||||
|
"description": "项目中是否存在需求不稳定的领域?是否有必要采用精益、敏捷或其他适应型技术来处理不稳定的需求,直至需求稳定且定义明确?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "治理",
|
||||||
|
"description": "组织是否拥有正式或非正式的审计和治理政策、程序和指南?"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "KA03",
|
"id": "KA03",
|
||||||
|
|||||||
@@ -90,6 +90,23 @@ export default function ProcessPracticePage() {
|
|||||||
}
|
}
|
||||||
}, [answeredCells, currentCellId])
|
}, [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(
|
const switchToCell = useCallback(
|
||||||
(cell: CellInfo) => {
|
(cell: CellInfo) => {
|
||||||
@@ -251,16 +268,9 @@ export default function ProcessPracticePage() {
|
|||||||
setShowAnswerForCell(null)
|
setShowAnswerForCell(null)
|
||||||
setInputLocked(false)
|
setInputLocked(false)
|
||||||
announceToScreenReader('答案已隐藏')
|
announceToScreenReader('答案已隐藏')
|
||||||
|
restoreFocus()
|
||||||
// 恢复焦点到第一个输入框
|
|
||||||
setTimeout(() => {
|
|
||||||
const firstInput = document.querySelector(
|
|
||||||
'.practice-input-area input'
|
|
||||||
) as HTMLInputElement
|
|
||||||
firstInput?.focus()
|
|
||||||
}, 100)
|
|
||||||
}
|
}
|
||||||
}, [showAnswerForCell])
|
}, [showAnswerForCell, restoreFocus])
|
||||||
|
|
||||||
// 自动过期检查
|
// 自动过期检查
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -270,14 +280,7 @@ export default function ProcessPracticePage() {
|
|||||||
if (remainingTime <= 0) {
|
if (remainingTime <= 0) {
|
||||||
setShowAnswerForCell(null)
|
setShowAnswerForCell(null)
|
||||||
setInputLocked(false)
|
setInputLocked(false)
|
||||||
|
restoreFocus()
|
||||||
// 恢复焦点
|
|
||||||
setTimeout(() => {
|
|
||||||
const firstInput = document.querySelector(
|
|
||||||
'.practice-input-area input'
|
|
||||||
) as HTMLInputElement
|
|
||||||
firstInput?.focus()
|
|
||||||
}, 100)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,18 +288,11 @@ export default function ProcessPracticePage() {
|
|||||||
setShowAnswerForCell(null)
|
setShowAnswerForCell(null)
|
||||||
setInputLocked(false)
|
setInputLocked(false)
|
||||||
announceToScreenReader('答案已自动隐藏')
|
announceToScreenReader('答案已自动隐藏')
|
||||||
|
restoreFocus()
|
||||||
// 恢复焦点
|
|
||||||
setTimeout(() => {
|
|
||||||
const firstInput = document.querySelector(
|
|
||||||
'.practice-input-area input'
|
|
||||||
) as HTMLInputElement
|
|
||||||
firstInput?.focus()
|
|
||||||
}, 100)
|
|
||||||
}, remainingTime)
|
}, remainingTime)
|
||||||
|
|
||||||
return () => clearTimeout(timer)
|
return () => clearTimeout(timer)
|
||||||
}, [showAnswerForCell])
|
}, [showAnswerForCell, restoreFocus])
|
||||||
|
|
||||||
// 点击格子切换(允许回顾已答对的格子)
|
// 点击格子切换(允许回顾已答对的格子)
|
||||||
const handleCellClick = useCallback(
|
const handleCellClick = useCallback(
|
||||||
|
|||||||
Reference in New Issue
Block a user