如何合并991px以上屏点击切换背景的重复JS函数实现精简?
精简重构方案
完全可以把重复逻辑整合,你原代码不仅冗余,还存在一个隐性问题:仅在页面首次加载时判断一次屏幕宽度,用户拖拽调整浏览器窗口尺寸时,交互不会自动适配宽度变化。
优化思路是把tab元素和对应背景图的关系统一用配置数组管理,抽离公共的事件绑定逻辑,同时监听媒体查询变化动态绑定/解绑事件,避免小屏幕下交互误触发、以及内存泄漏问题。
优化后代码如下:
// 定义屏幕宽度判断规则 const desktopMediaQuery = window.matchMedia('(min-width: 991px)') // 集中配置tab选择器与对应背景图的映射,后续新增/修改项只需要改这个数组 const tabMap = [ { selector: '.content1', bg: 'img1.jpg' }, { selector: '.content2', bg: 'img2.jpg' }, { selector: '.content3', bg: 'img3.jpg' }, { selector: '.content4', bg: 'img4.jpg' } ] const bgContainer = document.querySelector('.infrastructure') // 缓存已绑定的事件函数,方便后续解绑 const handlerCache = new Map() function updateTabInteractiveStatus(e) { const isOver991px = e.matches tabMap.forEach(item => { const tabEl = document.querySelector(item.selector) if (!tabEl) return // 先清除已绑定的旧事件,避免重复绑定 if (handlerCache.has(tabEl)) { tabEl.removeEventListener('click', handlerCache.get(tabEl)) handlerCache.delete(tabEl) } // 符合宽度要求时才绑定点击切换背景逻辑 if (isOver991px) { const clickFn = () => { bgContainer.style.backgroundImage = `url(${item.bg})` } tabEl.addEventListener('click', clickFn) handlerCache.set(tabEl, clickFn) } }) } // 初始化执行 updateTabInteractiveStatus(desktopMediaQuery) // 监听宽度变化,自动适配交互状态 desktopMediaQuery.addEventListener('change', updateTabInteractiveStatus)
这个写法的优势:
- 配置和逻辑分离,后续维护只需要修改
tabMap配置数组即可,不需要重复写事件判断、绑定的冗余代码 - 自动响应窗口尺寸变化,不会出现宽度小于991px时点击tab仍然切换背景的问题
- 增加了元素存在性校验,避免页面未渲染对应tab时抛出JS错误
- 事件绑定前做了去重处理,不会因为重复绑定导致点击一次触发多次逻辑的bug
- 小屏幕下会自动解绑事件,没有冗余的事件监听占用内存
内容的提问来源于stack exchange,提问作者Espskully
相关产品推荐
相关产品推荐

