如何避免Angular子组件的点击事件被过早触发
问题根因
点击搜索图标触发的点击事件会向上冒泡至document层面,搜索栏组件被渲染后立即绑定了document的click事件监听,同一个冒泡上来的点击事件会直接触发搜索栏的关闭逻辑,导致刚打开就关闭。你当前用的100ms延时属于Hack方案,本质是等本次点击事件的冒泡流程走完再启用关闭逻辑,存在时序兼容隐患。
最优解决方案:阻止搜索图标点击事件冒泡
该方案无需改动搜索栏核心逻辑,仅调整导航组件的图标点击事件即可,不会产生额外时序依赖:
修改 navigation.component.html
给搜索图标的点击事件添加阻止冒泡逻辑:
<i class="fas fa-search search-icon" (click)="openSearchBar(); $event.stopPropagation()"></i>
清理 search-bar.component.ts 冗余逻辑
删掉临时用的延时和searchMode变量,简化后的代码如下:
import { Component, ElementRef, ViewChild, Output, EventEmitter, } from '@angular/core'; @Component({ selector: 'app-search-bar', templateUrl: './search-bar.component.html', styleUrls: ['./search-bar.component.scss'], host: { '(document:click)': 'onClick($event)', }, }) export class SearchBarComponent { city = ''; @ViewChild('searchBar') searchBar!: ElementRef; @Output() closeSearch = new EventEmitter(); onSubmit() { console.log('submitted'); } onClick(event: Event) { if (!this.searchBar.nativeElement.contains(event.target)) { this.closeSearch.emit(); } } }
备选方案(不允许阻止冒泡场景)
如果业务逻辑要求不能阻止搜索图标点击事件冒泡,可以用微任务替代固定时长的宏任务延时,避免硬编码100ms的不稳定问题:
// search-bar.component.ts 的 ngOnInit 改为 ngOnInit(): void { // 微任务会在本次点击事件冒泡流程全部完成后立即执行,无固定延时 Promise.resolve().then(() => this.searchMode = true) }
内容的提问来源于stack exchange,提问作者mbbm9
相关产品推荐
相关产品推荐

