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

在Angular与Bootstrap中实现导航悬停下拉框的按钮可点击功能

导航下拉框无法点击按钮及自动隐藏问题解决

问题描述

  • 当前行为:鼠标悬停导航项时,下拉容器显示,但容器内的按钮无法点击。
  • 预期行为:悬停导航项时可点击下拉容器内的按钮;鼠标移出导航项和下拉容器范围后,容器自动隐藏。

问题原因

下拉容器与导航项是完全独立的DOM元素,当鼠标从导航项移动到下拉容器时,会立刻触发导航项的mouseleave事件,导致下拉容器被隐藏,因此无法完成按钮点击操作。同时两者不属于同一父容器,无法共享hover状态。

解决方案

方案1:调整DOM结构(推荐)

将下拉容器嵌套到对应导航项的父元素内部,这样鼠标在导航项和下拉容器之间移动时,不会触发mouseleave事件(因为它们属于同一个父元素的hover范围)。

修改后的HTML代码:

<div class="flex-container">
  <div *ngFor="let item of navigations">
    <ng-container *ngIf="item.type == 'dropdown'">
      <div
        class="dropdown p-0 position-relative"
        (mouseenter)="showDropdown(item)"
        (mouseleave)="hideDropdown(item)"
      >
        <a
          class="cs-link-white dropdown-toggle"
          href="#"
          role="button"
          aria-expanded="false"
        >
          {{ item.menuTitle }}
        </a>
        <!-- 下拉容器移至导航项内部 -->
        <div
          *ngIf="activeMenu?.menuCode === item.menuCode"
          style="height: 200px; width: 100%; background-color: #c8c8c8;"
          class="dropdown-menu position-absolute"
          [class.show]="isDropdownOpen[item.menuCode]"
        >
          <div>
            Hello from {{ item.menuCode }}
            <button (click)="triggerAction()">Button</button>
          </div>
        </div>
      </div>
    </ng-container>
    <ng-container *ngIf="item.type == 'link'">
      <div>
        <a class="cs-link-white" href="#">{{ item.menuTitle }}</a>
      </div>
    </ng-container>
  </div>
</div>

补充CSS定位样式:

.dropdown.position-relative {
  position: relative;
}

.dropdown-menu.position-absolute {
  position: absolute;
  top: 100%;
  left: 0;
  margin: 0;
  z-index: 1000;
}

方案2:定时器延迟隐藏(无需修改DOM结构)

如果无法调整DOM结构,可以通过定时器延迟下拉容器的隐藏,同时监听下拉容器的鼠标事件来控制显示状态:

修改后的TypeScript代码:

import { CommonModule } from '@angular/common';
import { Component, ElementRef, ViewChild } from '@angular/core';

interface NavigationItem {
  menuTitle: string;
  menuCode: string;
  type: 'dropdown' | 'link';
}

@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.css'],
  standalone: true,
  imports: [CommonModule],
})
export class NavigationComponent {
  activeMenu!: NavigationItem;
  hideTimer: any;

  isDropdownOpen: any = {
    dropdown1: false,
    dropdown2: false,
    dropdown3: false,
  };

  navigations: NavigationItem[] = [
    { menuTitle: 'Dropdown 1', menuCode: 'dropdown1', type: 'dropdown' },
    { menuTitle: 'Dropdown 2', menuCode: 'dropdown2', type: 'dropdown' },
    { menuTitle: 'Dropdown 3', menuCode: 'dropdown3', type: 'dropdown' },
    { menuTitle: 'Link1', menuCode: 'link1', type: 'link' },
    { menuTitle: 'Link2', menuCode: 'link2', type: 'link' },
  ];

  @ViewChild('dropdownContainer') dropdownContainer!: ElementRef;

  showDropdown(item: NavigationItem) {
    clearTimeout(this.hideTimer);
    this.activeMenu = item;
    this.isDropdownOpen[item.menuCode] = true;
  }

  hideDropdown(item: NavigationItem) {
    this.hideTimer = setTimeout(() => {
      this.isDropdownOpen[item.menuCode] = false;
    }, 300);
  }

  onDropdownEnter() {
    clearTimeout(this.hideTimer);
  }

  onDropdownLeave() {
    if (this.activeMenu) {
      this.isDropdownOpen[this.activeMenu.menuCode] = false;
    }
  }

  triggerAction() {
    console.log('button clicked');
  }
}

对应的HTML修改(添加鼠标事件监听):

<div class="flex-container">
  <div *ngFor="let item of navigations">
    <ng-container *ngIf="item.type == 'dropdown'">
      <div
        class="dropdown p-0"
        (mouseenter)="showDropdown(item)"
        (mouseleave)="hideDropdown(item)"
      >
        <a
          class="cs-link-white dropdown-toggle"
          href="#"
          role="button"
          aria-expanded="false"
        >
          {{ item.menuTitle }}
        </a>
      </div>
    </ng-container>
    <ng-container *ngIf="item.type == 'link'">
      <div>
        <a class="cs-link-white" href="#">{{ item.menuTitle }}</a>
      </div>
    </ng-container>
  </div>
</div>
<div
  *ngIf="activeMenu"
  style="height: 200px; width: 100%; background-color: #c8c8c8;"
  class="dropdown-menu"
  [class.show]="isDropdownOpen[activeMenu.menuCode]"
  (mouseenter)="onDropdownEnter()"
  (mouseleave)="onDropdownLeave()"
  #dropdownContainer
>
  <div>
    Hello from {{ activeMenu.menuCode }}
    <button (click)="triggerAction()">Button</button>
  </div>
</div>

界面截图

导航下拉框界面截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:05:57