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

TypeScript中如何优雅地批量为多个元素添加/移除类?

优化类切换的TypeScript代码

我有一个需要添加或移除类的开关,在我的.ts文件中编写了如下代码:

export default class extends Controller {
  static targets = [
    "InformationOne",
    "InformationTwo",
    "InformationThree",
    "InformationFour",
    "InformationSwitchOne",
    "InformationSwitchTwo"
  ];

  private InformationOne: HTMLElement[];
  private InformationTwo: HTMLElement[];
  private InformationThree: HTMLElement[];
  private InformationFour: HTMLElement[];
  private InformationSwitchOne: HTMLInputElement;
  private InformationSwitchTwo: HTMLInputElement;

  switchInformation(): void {
    if (this.InformationSwitchOne.checked) {
        this.InformationOne.forEach((item) => { item.classList.remove("d-none"); });
        this.InformationTwo.forEach((item) => { item.classList.add("d-none"); });
        this.InformationThree.forEach((item) => { item.classList.add("d-none"); });
        this.InformationFour.forEach((item) => { item.classList.add("d-none"); });
    } else if (this.InformationSwitchTwo.checked) {
        this.InformationTwo.forEach((item) => { item.classList.remove("d-none"); });
        this.InformationOne.forEach((item) => { item.classList.add("d-none"); });
        this.InformationThree.forEach((item) => { item.classList.add("d-none"); });
        this.InformationFour.forEach((item) => { item.classList.add("d-none"); });
    }
  }
}

现在的问题是,如何让以下代码更优雅?有没有办法一次性获取这三个元素并为它们执行classList.add操作,而非逐个处理?

this.InformationTwo.forEach((item) => { item.classList.add("d-none"); });
this.InformationThree.forEach((item) => { item.classList.add("d-none"); });
this.InformationFour.forEach((item) => { item.classList.add("d-none"); })

优化方案

1. 合并数组批量处理

直接把需要操作的数组合并成一个新数组,一次性遍历完成类添加操作:

[...this.InformationTwo, ...this.InformationThree, ...this.InformationFour]
  .forEach(item => item.classList.add("d-none"));

如果这类操作需要多次复用,可以在类里封装一个工具方法:

private addClassToGroups(groups: HTMLElement[][], className: string) {
  groups.flat().forEach(item => item.classList.add(className));
}

// 调用方式
this.addClassToGroups([this.InformationTwo, this.InformationThree, this.InformationFour], "d-none");

2. 统一管理所有信息元素

把所有信息元素数组统一存入一个集合,切换时先批量隐藏所有元素,再单独显示目标元素,大幅减少重复代码:

export default class extends Controller {
  static targets = [
    "InformationOne",
    "InformationTwo",
    "InformationThree",
    "InformationFour",
    "InformationSwitchOne",
    "InformationSwitchTwo"
  ];

  private InformationOne: HTMLElement[];
  private InformationTwo: HTMLElement[];
  private InformationThree: HTMLElement[];
  private InformationFour: HTMLElement[];
  private InformationSwitchOne: HTMLInputElement;
  private InformationSwitchTwo: HTMLInputElement;
  
  private allInfoGroups: HTMLElement[][] = [];

  connect() {
    this.allInfoGroups = [
      this.InformationOne,
      this.InformationTwo,
      this.InformationThree,
      this.InformationFour
    ];
  }

  switchInformation(): void {
    // 批量隐藏所有元素
    this.allInfoGroups.flat().forEach(item => item.classList.add("d-none"));
    
    // 根据开关状态显示对应元素
    if (this.InformationSwitchOne.checked) {
      this.InformationOne.forEach(item => item.classList.remove("d-none"));
    } else if (this.InformationSwitchTwo.checked) {
      this.InformationTwo.forEach(item => item.classList.remove("d-none"));
    }
  }
}

后续新增信息元素时,只需要把对应的数组加入allInfoGroups即可,无需修改多处逻辑,扩展性更强。

3. 用CSS类切换实现(更简洁的思路)

如果DOM结构允许,把显示逻辑交给CSS,通过切换父容器的类来控制子元素显示,彻底避免JS批量操作:

/* 基础样式:隐藏所有信息项 */
.info-container .info-item {
  display: none;
}
/* 选中开关一时显示对应项 */
.info-container.show-info-one .info-item.one {
  display: block;
}
/* 选中开关二时显示对应项 */
.info-container.show-info-two .info-item.two {
  display: block;
}

对应的JS代码简化为:

switchInformation(): void {
  const container = document.querySelector('.info-container');
  container?.classList.remove('show-info-one', 'show-info-two');
  
  if (this.InformationSwitchOne.checked) {
    container?.classList.add('show-info-one');
  } else if (this.InformationSwitchTwo.checked) {
    container?.classList.add('show-info-two');
  }
}

这种方式符合关注点分离原则,把样式控制交还给CSS,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:48:59