如何实现点击新弹窗时自动关闭已打开的弹窗?
解决弹窗互斥显示问题
你的问题出在每个弹窗的控制函数都是独立的,互相没有关联,所以打开新弹窗时不会自动关闭已打开的。下面给你两种可行的修改方案:
方案一:点击新弹窗自动关闭其他,同时保留当前弹窗的开关功能
这个方案既保证打开新弹窗时旧的自动关闭,也支持点击已打开的弹窗来关闭它。
修改后的代码
<script> function togglePopup(popupId) { // 先获取所有弹窗元素 const allPopups = document.querySelectorAll('.popuptext'); // 遍历所有弹窗,移除show类(关闭所有非当前弹窗) allPopups.forEach(popup => { if (popup.id !== popupId) { popup.classList.remove('show'); } }); // 切换当前弹窗的显示状态 const currentPopup = document.getElementById(popupId); currentPopup.classList.toggle('show'); } </script> <p class='popup' onclick='togglePopup("popup0")'>El Gringo <span class='popuptext' id='popup0'> 每当他因其他玩家打出的卡牌失去生命值时,格林戈从该玩家手牌中随机抽一张牌(每失去1点生命值抽一张)。<br>(3点生命值) </span> </p><br> <p class='popup' onclick='togglePopup("popup1")'>Willy the Kid <span class='popuptext' id='popup1'> 在他的回合中,他可以打出任意数量的"Bang!"卡牌。<br>(4点生命值) </span> </p><br> <p class='popup' onclick='togglePopup("popup2")'>Lucky Duke <span class='popuptext' id='popup2'> 每当需要"抽牌!"时,他从牌堆顶翻开两张牌,选择自己想要的结果,之后两张牌都弃置。<br>(4点生命值) </span> </p><br> <p class='popup' onclick='togglePopup("popup3")'>Kit Carlson <span class='popuptext' id='popup3'> 在他回合的第一阶段,他查看牌堆顶的三张牌,选择两张加入手牌,剩下的一张放回牌堆背面。<br>(4点生命值) </span> </p><br>
关键逻辑说明
- 把原来多个重复的
popup0()、popup1()合并成一个通用的togglePopup()函数,接收弹窗ID作为参数,大幅减少代码冗余。 - 每次触发函数时,先通过
document.querySelectorAll('.popuptext')获取所有弹窗,遍历移除除当前弹窗外的show类,实现关闭其他弹窗的效果。 - 最后用
toggle切换当前弹窗的显示状态,支持点击当前弹窗关闭它。
方案二:仅切换弹窗(点击新弹窗直接打开,关闭所有旧的,不支持点击当前关闭)
如果不需要点击已打开的弹窗关闭它,只需要切换到新弹窗,可以简化逻辑:
<script> function showPopup(popupId) { // 关闭所有弹窗 document.querySelectorAll('.popuptext').forEach(popup => { popup.classList.remove('show'); }); // 打开当前弹窗 document.getElementById(popupId).classList.add('show'); } </script> <!-- 这里的onclick调用改成showPopup即可 --> <p class='popup' onclick='showPopup("popup0")'>El Gringo <span class='popuptext' id='popup0'> 每当他因其他玩家打出的卡牌失去生命值时,格林戈从该玩家手牌中随机抽一张牌(每失去1点生命值抽一张)。<br>(3点生命值) </span> </p><br> <!-- 其余弹窗代码同理修改onclick参数 -->
额外优化建议
- 可以把所有
<script>标签合并到页面底部或者<head>里,不需要每个弹窗都单独加一个<script>,让代码更整洁。 - 如果后续还要添加更多弹窗,只需要复制
<p>部分,修改ID和内容,调用同一个函数即可,不需要再写新的控制函数。
内容的提问来源于stack exchange,提问作者user18302645
相关产品推荐
相关产品推荐

