在 Angular 和 Bootstrap 中,当鼠标悬停在导航项上时,如何单击展开的下拉列表中的按钮?

问题描述 投票:0回答:1

当前行为:将鼠标悬停在导航项上时,下拉容器变得可见,但无法单击容器内的按钮。

预期行为:将鼠标悬停在导航项上时,下拉容器应允许单击其中的按钮。此外,当鼠标悬停在导航项和下拉容器之外时,该容器应该隐藏。

这是 stackblitz 代码 link

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"
          data-bs-toggle="dropdown"
          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]"
>
  <div>
    Hello from {{ activeMenu.menuCode }}
    <button (click)="triggerAction()">Button</button>
  </div>
</div>

CSS:

.flex-container {
  background-color: #2f333a;
  display: flex;
  align-items: center;
}

.cs-link-white {
  display: flex;
  color: white;
  text-decoration: none;
  font-family: inherit;
  -webkit-box-align: center;
  align-items: center;
  padding: 0px 15px;
  min-height: 44px;
  letter-spacing: 0.2px;
  font-size: 14px;
  font-weight: 500;
  font-style: normal;
  line-height: normal;
}

.show {
  display: block;
}

ts:

import { CommonModule } from '@angular/common';
import { Component } 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;

  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',
    },
  ];

  constructor() {}

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

  hideDropdown(item: NavigationItem) {
    this.activeMenu = item;
    this.isDropdownOpen[item.menuCode] = false;
  }

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

angular typescript bootstrap-5 angular17
1个回答
0
投票

您只需添加一个

setTimeout
来等待鼠标悬停在下拉菜单上,然后使用相同的鼠标悬停事件切换标志!

import { CommonModule } from '@angular/common';
import { Component } 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 = {
    menuTitle: 'Dropdown 1',
    menuCode: 'dropdown1',
    type: 'dropdown',
  };

  isDropdownOpen: any = {
    our_products: false,
    home_kitchen: false,
    toys: 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: 'Dropdown 4',
      menuCode: 'dropdown4',
      type: 'dropdown',
    },
    {
      menuTitle: 'Dropdown 5',
      menuCode: 'dropdown5',
      type: 'dropdown',
    },
    {
      menuTitle: 'Dropdown 6',
      menuCode: 'dropdown6',
      type: 'dropdown',
    },
    {
      menuTitle: 'Link1',
      menuCode: 'link1',
      type: 'link',
    },
    {
      menuTitle: 'Link2',
      menuCode: 'link2',
      type: 'link',
    },
  ];

  isDropdownOpenv1 = false;

  constructor() {}

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

  hideDropdown(event: any, item: NavigationItem) {
    console.log(event);
    const relatedTarget = event?.relatedTarget;
    if (relatedTarget?.classList.contains('dropdown-menu')) {
      return;
    }
    this.activeMenu = item;
    setTimeout(() => {
      this.isDropdownOpen[item.menuCode] = false;
    });
  }

  isMobileView(): boolean {
    return window.innerWidth < 992;
  }

  showDropdownv1() {
    this.isDropdownOpenv1 = true;
  }

  hideDropdownv1() {
    this.isDropdownOpenv1 = false;
  }

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

堆栈闪电战

© www.soinside.com 2019 - 2024. All rights reserved.