javascript - 如何防止角子组件的点击事件过早触发?
问题描述
我试图创建一个搜索栏组件,该组件在单击其父组件中的搜索图标后打开,并在单击搜索栏外部后关闭。但是,在单击打开图标后,它立即在搜索栏组件中触发了一个 (document:click) 事件,结果导致它关闭得太早了。
我通过在搜索栏组件中创建一个“searchMode”变量并设置超时(在 ngOnInit 中)在 100 毫秒后将其设置为 true,找到了解决此问题的方法。但是,我想知道,是否有比设置超时更好的解决方案来解决这个问题?
(预期结果:用户单击导航组件中的搜索图标 -> 搜索栏组件显示在搜索图标的位置 -> 用户单击搜索栏组件外部 -> 搜索栏消失,搜索图标显示再次)
导航.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
})
export class NavigationComponent implements OnInit {
searchActive = false;
constructor() {}
ngOnInit(): void {}
openSearchBar(): void {
this.searchActive = true;
}
closeSearchBar() {
this.searchActive = false;
}
}
导航.component.html
<div class="weather-app__navigation">
<ul class="weather-app__navigation-list">
<li class="weather-app__navigation-list__item">
<i class="fas fa-bars bars-icon"></i>
</li>
<li class="weather-app__navigation-list__item">
<ng-container
*ngIf="searchActive; then searchBarContent; else searchIcon"
></ng-container>
</li>
<ng-template #searchBarContent
><app-search-bar (closeSearch)="closeSearchBar()"></app-search-bar
></ng-template>
<ng-template #searchIcon
><i class="fas fa-search search-icon" (click)="openSearchBar()"></i
></ng-template>
<li class="weather-app__navigation-list__item">
<i class="fas fa-info-circle about-icon"></i>
</li>
</ul>
</div>
搜索栏.component.ts
import {
Component,
OnInit,
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 implements OnInit {
searchMode = false;
city = '';
@ViewChild('searchBar') searchBar!: ElementRef;
@Output() closeSearch = new EventEmitter();
constructor() {}
ngOnInit(): void {
setTimeout(() => {
this.searchMode = true;
}, 100);
}
onSubmit() {
console.log('submitted');
}
onClick(event: Event) {
if (!this.searchMode) {
return;
}
if (!this.searchBar.nativeElement.contains(event.target)) {
this.closeSearch.emit();
}
}
}
搜索栏.component.html
<div class="weather-app__search-bar" #searchBar>
<form class="weather-app__search-bar__form" (ngSubmit)="onSubmit()">
<input type="text" name="city" [(ngModel)]="city" placeholder="City Name" />
<input type="submit" value="Submit" class="btn" />
</form>
</div>
解决方案
在搜索按钮上捕获的单击事件上使用event.stopPropogation()
,这将防止事件冒泡。
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
推荐阅读
- sql - ColdFusion sql问题
- oracle - 没有发生变异表异常
- vba - Excel vba:打开工作簿时分配全局变量;如果发生错误则被删除
- c# - 单元测试在 VSTS Build 上查找 roslyn 二进制文件的位置错误
- ios - 如何在 Xcode IB 中为 ARSCNView 设置首选渲染 API
- javascript - 将单页应用程序集成到 WordPress
- php - 在mysqli中添加所有重复值
- google-app-maker - 如何在 AppMaker 中导出数据库的架构
- selenium - 如何在量角器框架中使用 chrome 选项?
- r - 在 R 中打开 .bcp 文件