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

扩展管理器页面toggle按钮点击筛选后失效问题求助

问题修复方案

核心问题

筛选后toggle失效的原因:每次筛选都会重新生成卡片DOM,原来绑定在toggle上的change事件会随旧DOM被销毁,新生成的toggle没有绑定事件;另外showData里的循环会重复渲染DOM、重复绑定筛选按钮事件,导致逻辑混乱。

具体修复步骤

  1. 改用事件委托绑定toggle事件:把事件绑定到父元素.cards上,不管DOM怎么更新,新生成的toggle都能触发事件。
  2. 重构showData函数:移除内部的dataArr.forEach循环,避免重复渲染和重复绑定事件。
  3. 筛选按钮事件只绑定一次:把筛选按钮的事件监听移到fetch回调外,只初始化一次,不要放在循环中重复绑定。

修改后的完整代码

const cards = document.querySelector(".cards");
const all = document.getElementById("all");
const inactive = document.getElementById("inactive");
const active = document.getElementById("active");
const modeToggle = document.getElementById("mode-toggle");

let extensions = [];
let activated = [];
let inactivated = [];

class Extension {
    display(dataArr) {
        cards.innerHTML = `
            ${dataArr.map(extension => `
            <div class="card extension-card">
                <div class="ext-info">
                    <img src="${extension.logo}" alt="Extension logo" width="60">
                    <div class="text">
                        <h3 class="extension-title">${extension.name}</h3>
                        <p class="extension-description">${extension.description}</p>
                    </div>
                </div>
                <div class="functions">
                    <button class="btn btn-outline-secondary remove" id="remove">Remove</button>
                    <label class="switch">
                        <input type="checkbox" class="activate" data-id="${extension.id}">
                        <span class="slider"></span>
                    </label>
                </div>
            </div>
            `).join("")}
        `;
    }

    setCheckboxState(dataArr) {
        const activateToggles = document.getElementsByClassName("activate");
        dataArr.forEach(extension => {
            [...activateToggles].forEach(toggle => {
                if (toggle.getAttribute("data-id") === extension.id) {
                    toggle.checked = extension.isActive;
                }
            });
        });
    }

    static updateArrays() {
        activated = extensions.filter(ext => ext.isActive);
        inactivated = extensions.filter(ext => !ext.isActive);
    }
}

// 事件委托绑定toggle的change事件(只执行一次)
cards.addEventListener("change", (e) => {
    if (e.target.classList.contains("activate")) {
        const toggle = e.target;
        const extensionId = toggle.getAttribute("data-id");
        const extension = extensions.find(ext => ext.id === extensionId);
        if (extension) {
            extension.isActive = toggle.checked;
            Extension.updateArrays();
        }
    }
});

const showData = (dataArr) => {
    const extension = new Extension();
    extension.display(dataArr);
    extension.setCheckboxState(dataArr);
};

// 筛选按钮事件只绑定一次
all.addEventListener("click", () => {
    showData(extensions);
});

active.addEventListener("click", () => {
    Extension.updateArrays();
    showData(activated);
});

inactive.addEventListener("click", () => {
    Extension.updateArrays();
    showData(inactivated);
});

fetch("./data.json")
    .then(response => response.json())
    .then(data => {
        extensions = data;
        Extension.updateArrays();
        showData(extensions);
        console.log(extensions);
    })
    .catch(error => {
        console.log("Error fetching data");
    });

代码说明

  • 事件委托:通过父元素cards监听change事件,判断触发事件的元素是toggle时再处理逻辑,新生成的toggle无需重新绑定事件。
  • 移除重复逻辑:把筛选按钮和toggle的事件监听都移到外部,只初始化一次,避免重复绑定导致的多次触发问题。
  • 简化showData:只负责渲染DOM和设置checkbox状态,不再处理事件绑定,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:31:03