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

纯JS中UI元素事件监听器重复代码的常用模式

纯JavaScript中UI交互重复代码的通用解决模式

针对你遇到的UI元素交互逻辑重复问题,纯JavaScript里有几个通用的知名模式可以有效减少冗余代码,提升可维护性:

1. 单一职责函数封装

这是最基础也最常用的方式:把重复执行的DOM操作抽成独立的、职责单一的函数,在需要的地方直接调用。

比如针对你示例中的侧边菜单切换逻辑,封装成独立函数后,两个点击事件都可以复用:

// 封装重复的侧边菜单切换逻辑
function toggleSideMenu() {
  const sideMenu = document.querySelector('.sidemenu');
  sideMenu.classList.toggle('open');
}

// 主菜单点击事件
document.querySelector('.main-menu').addEventListener('click', () => {
  const mainMenu = document.querySelector('.main-menu');
  mainMenu.classList.toggle('open');
  
  // 复用封装好的函数
  if (document.querySelector('.sidemenu').classList.contains('open')) {
    toggleSideMenu();
  }
});

// 侧边菜单触发元素点击事件
document.querySelector('.sidemenu-trigger').addEventListener('click', toggleSideMenu);

你之前设想的openIfClosed()、toggleIf()这类辅助函数,本质就是这种模式的延伸——进一步把条件判断也封装成通用工具函数。

2. 行为委托(事件委托)

利用DOM事件冒泡机制,将多个子元素的事件监听绑定到共同的父元素上,通过判断事件触发源来执行对应逻辑。这种方式不仅减少重复的事件绑定代码,还能自动支持动态添加的元素。

示例:

// 绑定到父容器,统一处理所有菜单交互
document.querySelector('.menu-container').addEventListener('click', (e) => {
  const target = e.target;
  
  // 处理主菜单点击
  if (target.matches('.main-menu')) {
    target.classList.toggle('open');
    const sideMenu = document.querySelector('.sidemenu');
    if (sideMenu.classList.contains('open')) {
      sideMenu.classList.toggle('open');
    }
  }
  
  // 处理侧边菜单点击
  if (target.matches('.sidemenu-trigger')) {
    document.querySelector('.sidemenu').classList.toggle('open');
  }
});

3. 命令模式

将每个UI操作封装成独立的"命令"对象,每个对象包含execute()方法来执行具体逻辑。这种模式可以方便地复用、组合命令,甚至实现撤销/重做等复杂功能。

示例:

// 定义侧边菜单切换命令
const toggleSideMenuCmd = {
  execute() {
    const sideMenu = document.querySelector('.sidemenu');
    sideMenu.classList.toggle('open');
  }
};

// 定义主菜单切换命令,可组合其他命令
const toggleMainMenuCmd = {
  execute() {
    const mainMenu = document.querySelector('.main-menu');
    mainMenu.classList.toggle('open');
    
    // 组合命令:如果侧边菜单处于打开状态,执行关闭命令
    if (document.querySelector('.sidemenu').classList.contains('open')) {
      toggleSideMenuCmd.execute();
    }
  }
};

// 绑定事件,调用对应命令
document.querySelector('.main-menu').addEventListener('click', () => toggleMainMenuCmd.execute());
document.querySelector('.sidemenu-trigger').addEventListener('click', () => toggleSideMenuCmd.execute());

4. 状态管理模式

维护一个集中的状态对象,用来记录UI的状态(比如菜单是否打开),所有UI操作都通过修改状态来触发更新,避免直接重复操作DOM。这种方式让逻辑更清晰,状态变化可追踪。

示例:

// 集中管理菜单状态
const menuState = {
  mainMenuOpen: false,
  sideMenuOpen: false,
  
  // 根据状态更新UI
  syncUI() {
    document.querySelector('.main-menu').classList.toggle('open', this.mainMenuOpen);
    document.querySelector('.sidemenu').classList.toggle('open', this.sideMenuOpen);
  },
  
  // 主菜单切换逻辑
  toggleMainMenu() {
    this.mainMenuOpen = !this.mainMenuOpen;
    // 状态联动:主菜单打开时自动关闭侧边菜单
    if (this.mainMenuOpen && this.sideMenuOpen) {
      this.sideMenuOpen = false;
    }
    this.syncUI();
  },
  
  // 侧边菜单切换逻辑
  toggleSideMenu() {
    this.sideMenuOpen = !this.sideMenuOpen;
    this.syncUI();
  }
};

// 绑定事件,调用状态对象的方法
document.querySelector('.main-menu').addEventListener('click', () => menuState.toggleMainMenu());
document.querySelector('.sidemenu-trigger').addEventListener('click', () => menuState.toggleSideMenu());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:05:34