Razor Page循环生成多div时JS切换显示隐藏功能失效排查
Razor循环生成多元素后点击切换显示隐藏失效的修复方案
问题场景
需要实现点击按钮切换对应区域的显示/隐藏(点击显示、再次点击隐藏),单个元素场景下JS代码正常运行,但在Razor Page通过循环生成多个元素后功能失效。
原代码
Razor Page代码
@for (int i = 0; i < Model.quest.Count; i++) { <div class="row mt-12" > <div class="col-md-1"> <input type="checkbox" id="questcb" asp-for="@Model.quest[i].check"> <span>@(i + 1) Soru</span> </div> <div class="col-md-9"> <textarea class="form-control" asp-for=@Model.quest[i].Question rows="3" id="question" hidden></textarea> <label>@Model.quest[i].Question</label> </div> </div> <div class="row mt-12"> <div class="col-md-1" hidden> <button class="btn btn-outline-secondary" type="button" id="A" onclick="clickFunc(this.id)">A</button> </div> <div class="col-md-1" > A) </div> <div class="col-md-11" hidden="hidden"> <input type="text" asp-for=@Model.quest[i].Answer1 class="form-control" placeholder="" id="answer" aria-label="Example text with button addon" aria-describedby="button-addon1"> </div> <div class="col-md-11" id="Amod_@i" style="display:inline-block"> @Model.quest[i].Answer1 </div> <div class="col-md-2"> <button class="btn btn-primary" type="button" id="mod_@i" onclick="question(this.id)">Cevapları Görüntüle</button> </div> </div> }
原JS代码
let question = button => { let element = document.getElementById(`A${button}`); let buttonDOM = document.getElementById(`${button}`) let hidden = element.getAttribute("hidden"); if (hidden) { element.removeAttribute("hidden"); buttonDOM.innerText = "Cevapları Gizle"; } else { element.setAttribute("hidden", "hidden"); buttonDOM.innerText = "Cevapları Görüntüle"; } }
问题原因
- ID重复问题:循环中生成的
questcb、question、answer、A等ID会重复,HTML中ID必须唯一,导致JS无法正确定位目标元素。 - 目标元素ID拼接错误:JS中尝试通过
A${button}获取元素,但按钮ID是mod_@i,拼接后为Amod_@i,而实际需要切换的包含input的隐藏div未设置唯一ID,且与拼接后的ID不匹配。
修复方案
步骤1:修正Razor代码,确保元素ID唯一并传递正确参数
给需要切换的隐藏div添加唯一ID,同时修改按钮点击事件参数,直接传递当前索引:
@for (int i = 0; i < Model.quest.Count; i++) { <div class="row mt-12" > <div class="col-md-1"> <input type="checkbox" id="questcb_@i" asp-for="@Model.quest[i].check"> <span>@(i + 1) Soru</span> </div> <div class="col-md-9"> <textarea class="form-control" asp-for=@Model.quest[i].Question rows="3" id="question_@i" hidden></textarea> <label>@Model.quest[i].Question</label> </div> </div> <div class="row mt-12"> <div class="col-md-1" hidden id="btnA_@i"> <button class="btn btn-outline-secondary" type="button" onclick="clickFunc(@i)">A</button> </div> <div class="col-md-1" > A) </div> <!-- 给需要切换的div添加唯一ID --> <div class="col-md-11" hidden id="answerContainer_@i"> <input type="text" asp-for=@Model.quest[i].Answer1 class="form-control" placeholder="" id="answer_@i" aria-label="Example text with button addon" aria-describedby="button-addon1"> </div> <div class="col-md-11" id="Amod_@i" style="display:inline-block"> @Model.quest[i].Answer1 </div> <div class="col-md-2"> <!-- 点击事件传递索引i,方便定位元素 --> <button class="btn btn-primary" type="button" id="mod_@i" onclick="question(@i)">Cevapları Görüntüle</button> </div> </div> }
步骤2:修正JS代码,正确定位目标元素
根据索引获取对应的元素,处理显示隐藏逻辑:
let question = (index) => { // 获取需要切换的输入框容器 const answerContainer = document.getElementById(`answerContainer_${index}`); // 获取按钮元素 const buttonDOM = document.getElementById(`mod_${index}`); // 获取答案显示区域 const answerDisplay = document.getElementById(`Amod_${index}`); // 切换显示状态 const isHidden = answerContainer.hasAttribute('hidden'); if (isHidden) { answerContainer.removeAttribute('hidden'); answerDisplay.style.display = 'none'; buttonDOM.innerText = "Cevapları Gizle"; } else { answerContainer.setAttribute('hidden', 'hidden'); answerDisplay.style.display = 'inline-block'; buttonDOM.innerText = "Cevapları Görüntüle"; } }
说明
- 所有循环生成的元素ID都添加了
_@i后缀,保证唯一性。 - 点击事件直接传递循环索引,简化元素定位逻辑,避免ID拼接错误。
- 同时切换输入框容器和答案显示区域的状态,符合“显示编辑框/隐藏答案”的需求。
内容的提问来源于stack exchange,提问作者Berk KARASU
相关产品推荐
相关产品推荐

