jQuery slideToggle在窗口resize/ready后持续触发切换的问题排查
问题分析与修复方案
核心bug成因
每次窗口大小调整触发navigationMobile函数时,只要屏幕宽度小于768px,就会重复执行$(".js-second-title").click(...)代码——这会给目标元素叠加绑定多个相同的点击事件。当用户点击菜单标题时,多个slideToggle事件同时触发,导致菜单反复切换(展开/收起瞬间完成),看起来像是“持续触发切换”的bug。
你之前尝试的return false和CSS样式调整,都没触及“重复绑定事件”这个根本原因,所以无效。
修复方案(两种可选)
方案1:绑定事件前先解绑旧事件
在每次绑定点击事件前,先移除元素上已有的click事件,避免叠加:
function navigationMobile() { const windowWidth = $(window).width(); if (windowWidth < 768) { // 移除href并添加All链接的代码保持不变 $(".js-second-title").each(function () { const currentHref = $(this).attr('href'); $(this).removeAttr('href'); if ($(this).siblings('ul').find('.js-all-link').length === 0) { $(this).siblings('ul').prepend(`<li><a class="js-all-link" href="${currentHref}">All</a></li>`); } }); // 先解绑旧的click事件,再绑定新的 $(".js-second-title").off('click').click(function () { $(this).siblings('.js-menu').slideToggle(); $(this).toggleClass('js-open'); }); } else { // 恢复href的代码保持不变 $('.js-second-title').each(function () { if ($(this).attr('href') === undefined) { const allHref = $(this).siblings('ul').find('.js-all-link').attr('href'); $(this).attr('href', `${allHref}`); $(this).siblings('ul').find('.js-all-link').remove(); } }); // 桌面端重置菜单状态,避免残留移动端收起状态 $(".js-second-title").siblings('.js-menu').show(); $(".js-second-title").removeClass('js-open'); // 解绑移动端点击事件 $(".js-second-title").off('click'); } }
方案2:使用事件委托(更高效推荐)
把点击事件绑定移到navigationMobile函数外部,只绑定一次,同时在事件内部判断屏幕宽度是否满足触发条件。这种方式从根源避免重复绑定:
// 仅绑定一次点击事件,内部判断是否为移动端 $(".js-second-title").click(function () { const windowWidth = $(window).width(); if (windowWidth < 768) { $(this).siblings('.js-menu').slideToggle(); $(this).toggleClass('js-open'); } }); // 防抖函数:避免窗口resize时频繁触发函数(可选优化) function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(func, delay); }; } // 初始化与resize监听 $(document).ready(navigationMobile); $(window).on('resize', debounce(navigationMobile, 250)); function navigationMobile() { const windowWidth = $(window).width(); if (windowWidth < 768) { $(".js-second-title").each(function () { const currentHref = $(this).attr('href'); // 避免重复移除href和添加All链接 if (currentHref && $(this).siblings('ul').find('.js-all-link').length === 0) { $(this).removeAttr('href'); $(this).siblings('ul').prepend(`<li><a class="js-all-link" href="${currentHref}">All</a></li>`); } }); } else { $('.js-second-title').each(function () { if (!$(this).attr('href')) { const allHref = $(this).siblings('ul').find('.js-all-link').attr('href'); $(this).attr('href', allHref); $(this).siblings('ul').find('.js-all-link').remove(); } // 桌面端强制展开菜单,移除移动端样式 $(this).siblings('.js-menu').show(); $(this).removeClass('js-open'); }); } }
内容的提问来源于stack exchange,提问作者in2d
相关产品推荐
相关产品推荐

