You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义JavaScript弹窗关闭按钮失效问题求助

自定义弹窗关闭按钮失效问题

首次尝试用JavaScript开发自定义弹窗,遇到关闭按钮("x")失效的问题:按钮能正确定位到要关闭的div,但点击时无法移除active类。

HTML 代码

<div class="spot spot-2">
    <div class="pin"></div>
    <div class="contenuto-spot flex flex-col gap-3">
        <img class="chiudi-popup" src="img/chiudi.svg" />
        [---CONTENT---]
    </div>
</div>

JavaScript 原代码

const tooltips = function () {
    const spots = document.querySelectorAll(".spot");
        
    spots.forEach((spot) => {
        const contenuto = spot.querySelector(".contenuto-spot");
        const pin = spot.querySelector(".pin");
    
        spot.addEventListener("click", () => {
          let curActive = document.querySelector(".spot.active");
          let contActive = document.querySelector(".contenuto-spot.show");
          const chiudiPopup = document.querySelector(".chiudi-popup");
    
          spot.classList.add("active");
          contenuto.classList.add("show");
    
          if (curActive && curActive !== spot) {
            curActive.classList.toggle("active");
            contActive.classList.toggle("show");
          }
    
          chiudiPopup.addEventListener("click", () => {
            spot.classList.remove("active");
            contenuto.classList.remove("show");
          });
      });
});

问题原因分析

  1. 事件冒泡冲突:关闭按钮是.spot的子元素,点击关闭按钮时事件会冒泡到父元素的点击事件,导致刚移除active和show类,又被父元素事件重新添加回去。
  2. 重复绑定事件:每次点击.spot都会给关闭按钮绑定一次点击事件,多次点击后会触发多次移除操作,引发异常。
  3. 选择器范围错误:document.querySelector(".chiudi-popup")只会选中页面第一个匹配的关闭按钮,多弹窗场景下无法对应当前弹窗。

修复后的代码

JavaScript 修复版

const tooltips = function () {
    const spots = document.querySelectorAll(".spot");
        
    spots.forEach((spot) => {
        const contenuto = spot.querySelector(".contenuto-spot");
        // 提前获取当前弹窗专属的关闭按钮
        const chiudiPopup = spot.querySelector(".chiudi-popup");

        // 单独给关闭按钮绑定事件,避免重复绑定
        chiudiPopup.addEventListener("click", (e) => {
            // 阻止事件冒泡到父元素,避免触发spot的点击事件
            e.stopPropagation();
            spot.classList.remove("active");
            contenuto.classList.remove("show");
        });
    
        spot.addEventListener("click", () => {
            let curActive = document.querySelector(".spot.active");
            let contActive = document.querySelector(".contenuto-spot.show");

            // 若当前弹窗已激活,直接返回避免重复操作
            if (spot.classList.contains("active")) return;

            spot.classList.add("active");
            contenuto.classList.add("show");

            if (curActive && curActive !== spot) {
                curActive.classList.remove("active");
                contActive.classList.remove("show");
            }
        });
    });
};

// 调用初始化函数
tooltips();

关键修复点

  • 提前在循环内获取当前弹窗对应的关闭按钮,确保弹窗与按钮一一对应。
  • 将关闭按钮的事件绑定移出.spot的点击事件,避免重复绑定。
  • 给关闭按钮的点击事件添加e.stopPropagation(),阻止事件冒泡。
  • 增加激活状态判断,避免重复执行激活逻辑。

内容的提问来源于stack exchange,提问作者user2300053

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:20:43