屏幕尺寸变化时slideToggle多次触发问题求解决方案
解决resize事件内重复绑定click导致多次触发slideToggle的问题
你的问题核心是每次触发resize事件时,都会给.part-heading重复绑定click事件,屏幕宽度小于768时,resize触发多少次,click事件就会被绑定多少次,点击自然会多次执行slideToggle。下面给你几个可行的替代方案:
方案1:先解绑再绑定,避免重复绑定
每次resize时先移除之前的click事件,再根据屏幕尺寸决定是否重新绑定:
$(window).on("resize", function () { // 先清除所有已绑定的click事件 $(".part-heading").off("click"); if (screen.width < 768) { $(".part-heading").click(function (e) { $(this).next(".sections").slideToggle("slow"); }); } });
这个方案简单直接,确保每次resize后只有最新的click事件生效。
方案2:使用事件委托(推荐)
把click事件绑定到父级元素(比如document或固定的容器),只绑定一次,点击时再判断屏幕尺寸是否需要执行slideToggle,同时在resize时处理大屏幕下的菜单状态:
// 仅绑定一次事件委托,无需放在resize事件内 $(document).on("click", ".part-heading", function (e) { if (screen.width < 768) { $(this).next(".sections").slideToggle("slow"); } }); // 屏幕尺寸变化时,重置大屏幕下的菜单状态 $(window).on("resize", function () { if (screen.width >= 768) { $(".sections").show(); // 大屏幕下保持菜单展开 } });
事件委托的优势是不需要在resize里频繁绑定解绑事件,性能更优,逻辑也更清晰。
方案3:用标志位控制绑定状态
通过变量跟踪是否已经绑定了移动端菜单的click事件,只在状态变化时执行绑定或解绑:
let isMobileMenuActive = false; $(window).on("resize", function () { if (screen.width < 768) { if (!isMobileMenuActive) { $(".part-heading").click(function (e) { $(this).next(".sections").slideToggle("slow"); }); isMobileMenuActive = true; } } else { if (isMobileMenuActive) { $(".part-heading").off("click"); isMobileMenuActive = false; $(".sections").show(); // 恢复大屏幕下的菜单状态 } } });
这个方案可以减少不必要的DOM操作,只有在屏幕尺寸跨阈值(768px)时才修改事件绑定。
内容的提问来源于stack exchange,提问作者Suhaib Abedalla
相关产品推荐
相关产品推荐

