Angular 10中实现点击外部关闭循环生成的可切换显示区块的方法
实现方案
核心逻辑为新增全局点击事件监听,判断点击目标是否属于「图片+对应说明」的容器范围,若不属于则关闭所有已打开的说明即可,修改后不会影响原有的点击图片切换说明的逻辑。
1. 修改app.component.html
给循环的外层容器添加自定义类,方便后续判断点击区域:
<hello name="{{ name }}"></hello> <h3>How to show info of clicked image only</h3> <div *ngFor="let x of things; let i = index" class="img-item"> <img src="https://source.unsplash.com/200x200" alt="loading" (click)="clicked(i)" /> <div *ngIf="x.show"> <div class="names"> <div class="fullName">{{ x.data }}</div> <div>{{ x.data2 }}</div> </div> </div> </div>
2. 修改app.component.ts
补充生命周期钩子实现,注册全局点击监听,新增销毁监听的逻辑避免内存泄漏:
import { Component, Renderer2, ElementRef, OnInit, OnDestroy } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent implements OnInit, OnDestroy { name = 'Angular'; previousIndex: number = -1; private globalClickHandler: () => void; constructor(private renderer: Renderer2, private elementRef: ElementRef) {} ngOnInit() { // 注册全局点击监听 this.globalClickHandler = this.renderer.listen('document', 'click', (event) => { // 没有打开的说明直接跳过 const hasOpened = this.things.some(item => item.show); if (!hasOpened) return; // 判断点击目标是否在任意一个「图片+说明」的容器内 const allContainers = Array.from(this.elementRef.nativeElement.querySelectorAll('.img-item')); const clickedInside = allContainers.some(container => container.contains(event.target)); if (!clickedInside) { // 点击外部,关闭所有说明 this.things.forEach(item => item.show = false); this.previousIndex = -1; } }); } ngOnDestroy() { // 组件销毁时移除全局监听,避免内存泄漏 if (this.globalClickHandler) { this.globalClickHandler(); } } clicked(index) { // 校验点击的是同一张图片还是新图片 if (this.previousIndex >= 0 && this.previousIndex != index) { // 点击新图片时关闭上一张图片的说明 this.things[this.previousIndex].show = false; } // 更新索引,切换当前点击图片的说明显示状态 this.previousIndex = index; this.things[index].show = !this.things[index].show; } public things: Array<any> = [ { data: '图片1的信息:', data2: '仅显示图片1的说明', show: false, }, { data: '图片2的信息:', data2: '仅显示图片2的说明', show: false, }, { data: '图片3的信息:', data2: '仅显示图片3的说明', show: false, }, ]; }
内容的提问来源于stack exchange,提问作者uiankosh
相关产品推荐
相关产品推荐

