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

如何在父li拥有has-menu类时阻止链接打开,同时保留多级菜单的折叠展开功能

解决多级菜单折叠展开与链接跳转的冲突问题

我明白你遇到的困扰:既要让带has-menu类的父菜单点击时只执行折叠展开,不能跳转链接;又要保证不带该类的子菜单链接能正常打开,同时不能破坏菜单的折叠功能。咱们来一步步修复这个问题:

问题根源

原来的代码给所有<li>绑定了点击事件,当点击has-menu类<li>里的链接时,事件会冒泡到父<li>,触发e.preventDefault()导致链接无法打开;而且折叠逻辑的触发范围太广,只要点到<li>的任何区域都会触发,很容易和链接点击产生冲突。

解决方案

核心思路是区分点击目标,给不同的点击区域分配不同的行为:

  • 点击<li>里的链接时:判断父<li>是否有has-menu类,有则阻止链接跳转,否则允许正常打开;
  • 点击<li>的非链接区域(比如折叠符号、菜单文本)时:执行折叠展开逻辑,同时阻止事件冒泡避免影响上层菜单。

修改后的JavaScript代码如下:

$('li').click(function(e) {
  const $currentLi = $(this);
  // 判断点击的目标是不是a标签
  if ($(e.target).is('a')) {
    // 父li带has-menu类,阻止链接跳转
    if ($currentLi.hasClass('has-menu')) {
      e.preventDefault();
    }
    // 不带has-menu类则不干预,让链接正常跳转
  } else {
    // 点击的是非链接区域,执行折叠展开
    if ($currentLi.hasClass('has-menu')) {
      e.stopPropagation(); // 阻止事件冒泡到上层菜单
      $currentLi.find(".menu-wrapper > ul").toggleClass("menu-close");
      $currentLi.toggleClass("menu-open");
    }
  }
});

代码细节说明

  1. 目标区分:通过$(e.target).is('a')精准判断用户点击的是链接还是菜单的其他区域;
  2. 链接逻辑:只有当链接的父<li>没有has-menu类时,才允许正常跳转,完全符合需求中指定的可跳转链接规则;
  3. 折叠优化:仅在点击非链接区域时触发折叠,同时用e.stopPropagation()避免触发上层菜单的折叠事件,保证多级菜单的独立性。

完整可运行代码示例

<!DOCTYPE html>
<html>
<head>
  <style>
    ul{
      padding: 0;
      list-style: none;
    }
    ul li{
      padding: 5px 0;
      position: relative;
      padding-right: 20px; /* 给折叠符号留出空间,避免重叠 */
    }
    ul li a{
      width: 100%;
      display: inline-block;
    }
    .menu-close{
      display: none;
    }
    /* Main menu */
    .menu-main{
      width: 250px;
    }
    .has-menu:before{
      content: '+';
      position: absolute;
      right: 0;
      cursor: pointer; /* 提示用户该区域可点击 */
    }
    .has-menu.menu-open:before{
      content: '-' !important;
    }
  </style>
</head>
<body>
  <ul class="menu-main">
    <li class="has-menu">
      Test 1
      <div class="menu-wrapper">
        <ul class="menu-child menu-close">
          <li class="has-menu">
            <a href="https://www.google.com" target="_blank">Sub cat 1/1</a>
            <div class="menu-wrapper">
              <ul class="menu-subchild menu-close">
                <li>
                  <a href="https://www.google.com" target="_blank">Sub Sub cat 1/1</a>
                </li>
              </ul>
            </div>
          </li>
        </ul>
        <ul class="menu-child menu-close">
          <li>
            <a href="https://www.google.com" target="_blank">Sub cat 1/2</a>
          </li>
        </ul>
      </div>
    </li>
  </ul>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script>
    $('li').click(function(e) {
      const $currentLi = $(this);
      if ($(e.target).is('a')) {
        if ($currentLi.hasClass('has-menu')) {
          e.preventDefault();
        }
      } else {
        if ($currentLi.hasClass('has-menu')) {
          e.stopPropagation();
          $currentLi.find(".menu-wrapper > ul").toggleClass("menu-close");
          $currentLi.toggleClass("menu-open");
        }
      }
    });
  </script>
</body>
</html>

我还在CSS里加了一点小优化:给<li>增加右侧内边距避免文本和折叠符号重叠,给折叠符号加上指针光标提升交互体验。

内容的提问来源于stack exchange,提问作者user16462554

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 22:54:07