为什么JavaScript切换div显示的函数需要点击两次按钮才生效?如何修复?
问题原因
你遇到的首次点击需要两次才生效的问题,由以下几个错误共同导致:
- 全局计数变量初始值被默认点击事件修改:你在代码末尾主动调用了
document.getElementById("defaultOpen").click()触发默认按钮的点击事件,这会让全局的timesClicked初始值从0变成1,不是你预期的初始0状态。 - 变量提升导致的判断失效:函数开头的
if (name1 === 'Insurance' && timesClicked < 1)判断时,name1还没有被赋值(var声明的变量会提升,但赋值不会),此时name1为undefined,判断永远不成立。 - replace方法使用错误:
evt.currentTarget.className.replace(" active", "")不会修改原类名字符串,必须把替换后的结果重新赋值给className才会生效。 - 全局计数逻辑适配性差:全局的
timesClicked没有和按钮状态绑定,只要点击过任意按钮就会修改计数,逻辑很容易混乱。
修复方案
我们可以简化逻辑,不需要额外的全局计数变量,直接通过当前点击按钮的状态、当前激活的内容判断即可,修正后的代码如下:
function openDiv(evt, divName, divName2) { // 先获取当前按钮、所有内容、所有按钮 const tabcontent = document.getElementsByClassName("tabcontent"); const tabcontent2 = document.getElementsByClassName("tabcontent2"); const tablinks = document.getElementsByClassName("tablinks"); const currentBtn = evt.currentTarget; // 情况1:当前按钮已经是激活状态,点击就切回Insurance if (currentBtn.classList.contains("active")) { // 切到Insurance的内容 document.getElementById('Insurance').style.display = "block"; document.getElementById('Insurance2').style.display = "block"; // 移除当前按钮的激活态,给默认按钮加激活态 currentBtn.classList.remove("active"); document.getElementById("defaultOpen").classList.add("active"); // 隐藏其他内容 for (let i = 0; i < tabcontent2.length; i++) { if (tabcontent[i].id !== 'Insurance') tabcontent[i].style.display = "none"; if (tabcontent2[i].id !== 'Insurance2') tabcontent2[i].style.display = "none"; } return; } // 情况2:当前按钮未激活,点击切换到对应内容 // 先隐藏所有内容、清除所有按钮激活态 for (let i = 0; i < tabcontent2.length; i++) { tabcontent[i].style.display = "none"; tabcontent2[i].style.display = "none"; } for (let i = 0; i < tablinks.length; i++) { tablinks[i].classList.remove("active"); } // 显示对应内容、给当前按钮加激活态 document.getElementById(divName).style.display = "block"; document.getElementById(divName2).style.display = "block"; currentBtn.classList.add("active"); } // 页面加载默认打开Insurance,不需要主动触发点击事件避免逻辑混乱 document.getElementById("defaultOpen").classList.add("active"); document.getElementById("Insurance").style.display = "block"; document.getElementById("Insurance2").style.display = "block";
上述代码用classList方法操作类名,比直接操作className更安全,不会出现重复加类、替换失效的问题,逻辑也更清晰,首次点击就能正常切换状态。
内容的提问来源于stack exchange,提问作者Dan M
相关产品推荐
相关产品推荐

