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

如何结合HTML元素高效运用对象编写可维护前端代码

人才管理系统下拉菜单OOP封装问题反馈

正在开发员工人才管理系统网站,开发下拉菜单模块时虽已采用面向对象(OOP)思路实现功能,但存在代码结构混乱、可维护性差的问题。目前仅掌握OOP基础概念,不清楚如何在实际项目中清晰、简洁地完成HTML元素与对象的结合封装,落地过程中遇到三类核心问题:

  • 对象实例化与事件绑定流程冗余:通过for循环为人才门户中每个代表候选人的可切换菜单创建对象实例后,需要二次遍历实例列表,为各菜单绑定对应对象方法作为点击事件,实现方式不直观、运行效率偏低。
  • 类内部条件判断过多:考虑到后续需要复用该对象实现其他菜单,而不同菜单的特性存在差异(例如此次实现的菜单点击后有淡入动画,但并非所有可切换菜单都需要该特性),在类中写了大量if判断处理可选配置,导致代码可读性、可维护性大幅下降。
  • 事件绑定逻辑的封装边界不清晰:不认可当前额外遍历元素绑定事件的实现方式,曾考虑将事件绑定逻辑全部封装到对象内部,但不确定该做法是否属于不良实践。

后续计划在表单、按钮、可切换菜单、导航栏等各类组件中使用OOP实现,核心诉求是掌握清晰简洁的HTML元素转对象封装方法。此前学习过设计模式相关内容,认为相关概念偏进阶,适合在扎实掌握对象基础用法后再深入学习;目前比较认可建造者(Builder)模式,正在单独分支上尝试基于该模式优化当前场景的实现,以下为当前的ToggleMenu类定义与初始化实现代码,寻求相关实践思路、优化建议与学习方向。

ToggleMenu 类实现代码

class ToggleMenu {
    constructor(wrapper, menu, openIcon, closeIcon, title, hiddenMenu) {
        this.wrapper = wrapper
        this.menu = menu
        this.openIcon = openIcon
        this.closeIcon = closeIcon
        this.title = title
        this.hiddenMenu = hiddenMenu
        this.toggled = false
    }
    props() {
        console.log(this.menu)
        console.log(this.openIcon)
        console.log(this.closeIcon)
        console.log(this.title)
        console.log(this.hiddenMenu)
        console.log(this.toggled)
    }
    openHiddenMenu(config) {
        if (config == undefined){
            config = {}
        }
        if (config.menuBackGroundColor !== undefined){
            this.menu.style.backgroundColor = config.menuBackGroundColor
        }
        if (config.titleColor !== undefined){
            this.title.style.color = config.titleColor
        }
        if (config.hiddenMenuDisplay !== undefined){
            this.hiddenMenu.style.display = config.hiddenMenuDisplay
        }
        if (config.hiddenMenuAnimation !== undefined){
            this.hiddenMenu.style.animationName = config.hiddenMenuAnimation
        }
        if(config.menuAnimation !== undefined){
            this.menu.style.animationName = config.menuAnimation
        }
        this.openIcon.style.display = 'none'
        this.closeIcon.style.display = 'block'
        this.toggled = true
    }
    closeHiddenMenu(config){
        if (config == undefined){
            config = {}
        }
        if (config.menuAnimation !== undefined && this.toggled == true){
            this.menu.style.animationName = config.menuAnimation
        }
        this.menu.style.backgroundColor = ''
        this.openIcon.style.display = ''
        this.closeIcon.style.display = ''
        this.title.style.color = ''
        this.hiddenMenu.style.display = ''
        this.toggled = false
    }
}

菜单初始化逻辑代码

const initCandidateMenus = () => {
    let candidateToggleMenus = document.getElementsByClassName('candidate-toggle-menu')
    let candidateToggleWrappers = document.getElementsByClassName('candidate-toggle-menu-wrapper')
    let hiddenMenus = document.getElementsByClassName('hidden-candidate-menu')
    let toggleMenus = []
    // 收集所有下拉菜单实例
    for (x = 0; x < candidateToggleMenus.length; x++){
        let toggleMenu = new ToggleMenu(
            candidateToggleWrappers[x],
            candidateToggleMenus[x],
            candidateToggleMenus[x].getElementsByClassName('candidate-open-icon')[0],
            candidateToggleMenus[x].getElementsByClassName('candidate-close-icon')[0],
            candidateToggleMenus[x].getElementsByClassName('candidate-name')[0],
            hiddenMenus[x],
        )
        toggleMenus.push(toggleMenu)
    }
    // 遍历实例绑定交互事件
    for (x = 0; x < toggleMenus.length; x++){
        let currentMenu = toggleMenus[x]
        currentMenu.openIcon.addEventListener('click', () => {
            // 关闭其他所有已打开的下拉菜单
            for (y = 0; y < toggleMenus.length; y++){
                toggleMenus[y].closeHiddenMenu()
            }
            // 打开当前选中菜单
            currentMenu.openHiddenMenu({
                menuBackGroundColor: 'var(--main-clr)',
                titleColor: 'var(--white)',
                menuAnimation: 'fade-title-color',
                hiddenMenuDisplay: 'flex',
                hiddenMenuAnimation: 'open-hidden-menu'
            })
        })
        currentMenu.closeIcon.addEventListener('click', () => {
                // 关闭当前菜单
                currentMenu.closeHiddenMenu()
        })
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:39:50