JavaScript绑定的toggle点击事件首次需点击两次才触发如何解决?
问题根因
你遇到的首次点击需触发两次的问题,核心原因是element.style只能读取元素的行内样式属性,无法读取CSS样式表中定义的样式。
页面初始加载时,你的desc1/desc2/desc3的display: none是写在CSS样式表中的,没有直接写在元素的style行内属性里,所以首次点击判断desc.style.display === 'none'时,拿到的值是空字符串,判断不成立,会先走else分支把display设为none,等于第一次点击没有触发你预期的显示逻辑,第二次点击时行内已经有display: none的属性了,才能正常触发。
解决方案
方案1:给元素添加行内初始样式
直接在对应的details1/details2/details3DOM元素上添加行内样式,让初始状态可以被element.style读取:
<div id="details1" style="display: none">...</div> <div id="details2" style="display: none">...</div> <div id="details3" style="display: none">...</div>
方案2:使用getComputedStyle读取实际生效的样式
替换判断逻辑,用window.getComputedStyle()获取元素最终渲染的真实样式,不受行内/样式表的限制:
readMore1.onclick = function() { // 读取真实生效的display属性 const currentDisplay = window.getComputedStyle(desc1).display; if (currentDisplay === 'none') { desc1.style.display = 'block'; readMore1.style.color = 'DeepPink'; readMore1.innerText = 'Read Less'; } else { desc1.style.display = 'none'; readMore1.style.color = ''; readMore1.innerText = 'Read More'; } } // readMore2、readMore3的点击事件同理修改即可
方案3(更推荐):用class切换实现toggle逻辑
避免直接操作行内样式,通过切换CSS类实现状态管理,代码更简洁易维护,还可以 eliminate 重复逻辑:
首先定义CSS类:
.hidden { display: none; } .read-more-active { color: DeepPink; }
然后修改JS逻辑:
// 统一配置所有切换映射,不用写三份重复代码 const toggleMap = [ { btnId: 'show-card-1', descId: 'details1' }, { btnId: 'show-card-2', descId: 'details2' }, { btnId: 'show-card-3', descId: 'details3' } ] toggleMap.forEach(({btnId, descId}) => { const btn = document.getElementById(btnId); const desc = document.getElementById(descId); btn.onclick = function() { const isHidden = desc.classList.toggle('hidden'); btn.classList.toggle('read-more-active', !isHidden); btn.innerText = isHidden ? 'Read More' : 'Read Less'; } })
初始状态给details1/details2/details3加上hidden类即可。
内容的提问来源于stack exchange,提问作者Nima Zarei
相关产品推荐
相关产品推荐

