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

将CSS hover事件转换为JavaScript点击事件以适配移动端多级下拉菜单

将CSS hover事件转换为JavaScript点击事件以适配移动端多级下拉菜单

我太懂你的困扰了——PC端靠CSS :hover做的多级下拉菜单用着顺风顺水,但移动端用户根本触发不了hover,换成点击逻辑是刚需,而且你之前用toggle时踩了多子菜单互斥的坑对吧?这就给你一套落地的解决方案:

第一步:重构CSS,用类替代hover控制显示

先把原来依赖hover的样式逻辑改成通过.active类来切换,这样JS只需要操作这个类就行,比直接改display更灵活也更好维护:

/* 初始状态:隐藏所有子菜单 */
.pages-links-sub div.dropdown-contentc {
  display: none;
}

.columnb-sub > .pages-links-sub {
  display: none;
}

/* 用.active类替代hover逻辑,控制子菜单显示 */
.columnb-sub.active > .pages-links-sub {
  display: block;
}

.columnb-sub.active > .pages-links-sub div.dropdown-contentc {
  display: block;
}

第二步:用jQuery实现点击控制(解决多菜单互斥问题)

你之前用toggle出问题,核心是没处理「打开当前菜单时自动关闭其他所有菜单」的逻辑,下面的代码正好补上这个缺口:

$(document).ready(function() {
  // 给所有子菜单的触发按钮绑定点击事件
  $('.columnb-sub > a').on('click', function(e) {
    // 阻止默认的锚点跳转行为(因为你的href是#)
    e.preventDefault();
    
    // 获取当前点击的子菜单容器
    const currentSubMenu = $(this).closest('.columnb-sub');
    // 判断当前菜单是否处于展开状态
    const isAlreadyActive = currentSubMenu.hasClass('active');
    
    // 先统一关闭所有子菜单
    $('.columnb-sub').removeClass('active');
    
    // 如果当前菜单之前是收起的,就展开它;如果是展开的,就保持收起
    if (!isAlreadyActive) {
      currentSubMenu.addClass('active');
    }
  });

  // 【可选优化】点击页面空白区域自动收起所有子菜单
  $(document).on('click', function(e) {
    if (!$(e.target).closest('.columnb-sub').length) {
      $('.columnb-sub').removeClass('active');
    }
  });
});

核心逻辑说明

  1. 点击子菜单触发链接时,先拦住默认的锚点跳转行为,避免页面抖一下
  2. 先把所有子菜单的.active类移除,从根源保证同一时间只有一个子菜单能展开
  3. 再根据当前菜单的状态决定是否展开:收起状态就展开,展开状态就保持收起(实现toggle的交互)
  4. 空白区域点击关闭是加分项,能让用户操作更符合直觉

原生JavaScript版本(无需依赖jQuery)

要是你不想用jQuery,用原生JS也能实现完全一样的效果:

document.addEventListener('DOMContentLoaded', function() {
  // 获取所有子菜单触发按钮
  const subMenuTriggers = document.querySelectorAll('.columnb-sub > a');
  
  subMenuTriggers.forEach(trigger => {
    trigger.addEventListener('click', function(e) {
      e.preventDefault();
      const currentSubMenu = this.closest('.columnb-sub');
      const isAlreadyActive = currentSubMenu.classList.contains('active');
      
      // 关闭所有子菜单
      document.querySelectorAll('.columnb-sub').forEach(menu => {
        menu.classList.remove('active');
      });
      
      // 切换当前菜单状态
      if (!isAlreadyActive) {
        currentSubMenu.classList.add('active');
      }
    });
  });

  // 【可选优化】点击空白处关闭所有子菜单
  document.addEventListener('click', function(e) {
    if (!e.target.closest('.columnb-sub')) {
      document.querySelectorAll('.columnb-sub').forEach(menu => {
        menu.classList.remove('active');
      });
    }
  });
});

改完之后不管是PC端点击还是移动端触摸,都能完美触发子菜单的展开/收起,完全解决了多菜单互斥的问题,和你原来的hover逻辑效果一致,只是触发方式换成了更适配移动端的点击~

备注:内容来源于stack exchange,提问作者Dion Fitzgerald

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:23:10