如何合并三段仅类名不同的jQuery滚动事件处理代码?
问题
我用三段逻辑完全一致的jQuery代码实现页面滚动时给指定元素添加/移除类,只是目标元素类名和操作类名不同。但单独引入这三段代码会影响页面性能,请问怎么把它们合并成一段?
三段代码如下:
第一段:
jQuery(document).on('scroll', (e) => { if (document.body.scrollTop > 70 || document.documentElement.scrollTop > 70) { console.log('now'); jQuery('.ast-primary-header-bar').addClass('headercoloring'); } else { console.log('no'); jQuery('.ast-primary-header-bar').removeClass('headercoloring'); } })
第二段:
jQuery(document).on('scroll', (e) => { if (document.body.scrollTop > 70 || document.documentElement.scrollTop > 70) { console.log('now'); jQuery('.astra-logo-svg').addClass('filterr'); } else { console.log('no'); jQuery('.astra-logo-svg').removeClass('filterr'); } })
第三段:
jQuery(document).on('scroll', (e) => { if (document.body.scrollTop > 70 || document.documentElement.scrollTop > 70) { console.log('now'); jQuery('.ast-below-header-bar').addClass('headernarrowing'); } else { console.log('no'); jQuery('.ast-below-header-bar').removeClass('headernarrowing'); } })
解决方案
你可以把需要操作的「目标元素选择器-对应类名」整理成一个配置数组,只绑定一次scroll事件,在事件回调里批量处理所有元素的类切换,这样就能避免重复绑定scroll事件带来的性能浪费。
合并后的基础代码
// 把要操作的元素和类名配对存到数组里 const elementClassPairs = [ ['.ast-primary-header-bar', 'headercoloring'], ['.astra-logo-svg', 'filterr'], ['.ast-below-header-bar', 'headernarrowing'] ]; // 只绑定一次scroll监听 jQuery(document).on('scroll', (e) => { // 统一判断滚动状态 const isScrolled = document.body.scrollTop > 70 || document.documentElement.scrollTop > 70; // 只打印一次日志,不用重复输出 console.log(isScrolled ? 'now' : 'no'); // 遍历数组,批量处理每个元素的类添加/移除 elementClassPairs.forEach(([selector, className]) => { const $element = jQuery(selector); if (isScrolled) { $element.addClass(className); } else { $element.removeClass(className); } }); });
进阶性能优化:防抖处理
scroll事件在滚动过程中会触发非常频繁,哪怕合并了代码,也可能产生不必要的计算。可以添加防抖函数,让回调只在滚动停止100毫秒后执行,进一步降低性能消耗:
// 配置数组不变 const elementClassPairs = [ ['.ast-primary-header-bar', 'headercoloring'], ['.astra-logo-svg', 'filterr'], ['.ast-below-header-bar', 'headernarrowing'] ]; // 防抖函数:延迟执行回调,避免滚动时频繁触发 function debounce(func, delay = 100) { let timer; return function() { clearTimeout(timer); timer = setTimeout(() => func.apply(this, arguments), delay); }; } // 把滚动处理逻辑用防抖包装 const handleScroll = debounce(() => { const isScrolled = document.body.scrollTop > 70 || document.documentElement.scrollTop > 70; console.log(isScrolled ? 'now' : 'no'); elementClassPairs.forEach(([selector, className]) => { const $element = jQuery(selector); isScrolled ? $element.addClass(className) : $element.removeClass(className); }); }); // 绑定防抖后的处理函数 jQuery(document).on('scroll', handleScroll);
内容的提问来源于stack exchange,提问作者Selcuk xD
相关产品推荐
相关产品推荐

