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

JS多选框实现植物光照需求筛选功能失效问题求助

植物光照筛选功能失效的问题排查与修复

问题概述

使用HTML、SCSS和JS构建植物概览页面,通过多选框按植物光照需求筛选,但勾选多选框后完全无效果,控制台无任何输出。

核心问题分析

  • DOM元素获取时机错误:初始化时执行let plantcard = Array.from(document.querySelectorAll(".plantcard")),但植物卡片是通过fetch异步加载生成的,此时页面中还没有.plantcard元素,导致plantcard为空数组,后续筛选逻辑遍历空数组自然无效果。
  • 筛选逻辑依赖的标识缺失:生成植物卡片时,未给卡片添加对应光照值的类名,代码中尝试通过_.intersection(Array.from(el.classList), checked.checklight)匹配选中的光照值,但卡片本身没有携带光照相关class,永远无法匹配成功。
  • 事件绑定时机隐患:事件监听的绑定未确保在DOM完全加载后执行,可能因DOM未就绪导致元素获取失败。

修复步骤与代码调整

1. 调整卡片生成逻辑,添加光照标识类名

在生成卡片的模板中,给<article>标签添加对应光照值的class(如light-${data.Light}),同时在卡片生成完成后更新plantcard数组:

getPlants().then((data) => {
  data.forEach((data) => {
    plantcards.insertAdjacentHTML(
      "afterbegin",
      `<article class="plantcard light-${data.Light}">
        <!-- 原有卡片内容保持不变 -->
      </article>`
    );
  });
  // 卡片生成后更新DOM元素数组
  plantcard = Array.from(document.querySelectorAll(".plantcard"));
});

2. 修正筛选逻辑,移除不必要依赖

修改setVisibility函数,直接检查卡片的光照标识是否匹配选中的筛选值:

function setVisibility() {
  const selectedLights = checked.checklight;
  // 可选:实时获取卡片,避免异步加载导致的数组过期问题
  const currentPlantCards = Array.from(document.querySelectorAll(".plantcard"));

  currentPlantCards.forEach((el) => {
    // 提取卡片对应的光照值
    const cardLightClass = Array.from(el.classList).find(cls => cls.startsWith('light-'));
    if (!cardLightClass) {
      el.style.display = "block";
      return;
    }
    const cardLightValue = cardLightClass.split('-')[1];

    // 筛选规则:无选中项则全显示,否则匹配选中值
    const shouldShow = selectedLights.length === 0 || selectedLights.includes(cardLightValue);
    el.style.display = shouldShow ? "block" : "none";
  });
}

3. 确保事件监听在DOM就绪后绑定

将事件监听代码放在DOMContentLoaded事件中,保证DOM元素已加载完成:

document.addEventListener('DOMContentLoaded', () => {
  allCheckboxes = document.querySelectorAll("input[type=checkbox]");
  allCheckboxes.forEach(el => {
    el.addEventListener("change", toggleCheckbox);
  });
  // 初始化选中状态
  getChecked("checklight");
});

4. 调整全局变量初始值

将plantcard初始化为空数组,后续在卡片生成后更新:

let plantcard = [];

完整修复后的JS代码示例

let plantsArr = [];
const plantcards = document.getElementById("plantcards");

let allCheckboxes = [];
let plantcard = [];
let checked = {};

async function getPlants() {
  try {
    const response = await fetch("../files/pflanzen.json", {
      method: "GET",
    });

    if (!response.ok) {
      throw new Error(`Error! status: ${response.status}`);
    }

    let data = await response.json();

    for (const key in data) {
      plantsArr.push(data[key]);
    }

    return data;
  } catch (error) {
    console.log(error);
  }
}

/* Load plants */
getPlants().then((data) => {
  data.forEach((data) => {
    plantcards.insertAdjacentHTML(
      "afterbegin",
      `<article class="plantcard light-${data.Light}">
        <div class="article-wrapper">
          <figure>
            <img src="../images/plant_types/${data.Image}" alt="${data.Name}" />
          </figure>
          <div class="article-body">
            <h2>${data.Name}</h2>
            <h3>${data.NameLatin}</h3>
            <p>
               Standort: ${getPlantLight(data.Light)}<br/>
            </p>
            <a href="#" class="read-more">
              Read more <span class="sr-only">about this is some title</span>
              <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd" />
              </svg>
            </a>
          </div>
        </div>
      </article>`
    );
  });
  // 更新plantcard数组
  plantcard = Array.from(document.querySelectorAll(".plantcard"));
});

function getChecked(name) {
  checked[name] = Array.from(
    document.querySelectorAll(`input[name="${name}"]:checked`)
  ).map(function (el) {
    return el.value;
  });
}

function toggleCheckbox(e) {
  getChecked(e.target.name);
  setVisibility();
}

function setVisibility() {
  const selectedLights = checked.checklight;
  const currentPlantCards = Array.from(document.querySelectorAll(".plantcard"));

  currentPlantCards.forEach((el) => {
    const cardLightClass = Array.from(el.classList).find(cls => cls.startsWith('light-'));
    if (!cardLightClass) {
      el.style.display = "block";
      return;
    }
    const cardLightValue = cardLightClass.split('-')[1];
    const shouldShow = selectedLights.length === 0 || selectedLights.includes(cardLightValue);
    el.style.display = shouldShow ? "block" : "none";
  });
}

// DOM就绪后绑定事件
document.addEventListener('DOMContentLoaded', () => {
  allCheckboxes = document.querySelectorAll("input[type=checkbox]");
  allCheckboxes.forEach(el => {
    el.addEventListener("change", toggleCheckbox);
  });
  getChecked("checklight");
});

额外说明

  • 如果getPlantLight是自定义函数,需确保它能正确将data.Light的数值转换为对应文本(如0→halbschattig)。
  • 也可以用自定义属性替代class存储光照值,比如给卡片添加data-light="${data.Light}",筛选时通过el.dataset.light获取值,逻辑类似。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:14:51