简体   繁体   English

检测元素外部的点击 Angular 9 - 多个实例

[英]Detect Click Outside of Element Angular 9 - Multiple Instances

In my app, on click of an element I am showing a tooltip that contains additional information.在我的应用程序中,单击一个元素时,我会显示一个包含附加信息的工具提示 This is available for all elements in a list.这适用于列表中的所有元素。 I would like to be able to close the expansion on click of anything outside of the tooltip .我希望能够在单击工具提示之外的任何内容时关闭扩展。

The concept is essentially what is covered in this answered question but I need it to work if there are multiple instances of the element.这个概念本质上是这个已回答问题所涵盖的内容,但如果元素有多个实例,我需要它来工作。 I have attempted using ViewChildren for the elements rather than ViewChild as there are multiple but that doesn't achieve what I'm looking for.我尝试将 ViewChildren 用于元素而不是 ViewChild,因为有多个元素,但这并没有达到我想要的效果。 I would like to avoid using any packages that are not already available from @angular/core , rxjs etc., if possible.如果可能,我想避免使用@angular/corerxjs等尚未提供的任何软件包。 See below a simplified and condensed version of what I've attempted with no success so far.请参阅下面的简化版本,这是我迄今为止没有成功的尝试。

HTML HTML

<li *ngFor="let listItem of listItems;">
  <p>
    <span *ngIf="showTooltip" class="item-tooltip" #itemTooltip>
      Tooltip with {{ listItem.detailed }}
      <span (click)="toggleTooltip()">Close</span>
    </span>
    <span (click)="toggleTooltip()" #tooltipTrigger>{{ listItem.blurb }}</span>
  </p>
</li>

TS TS

@ViewChildren('itemTooltip') itemTooltip: ElementRef;
@ViewChildren('tooltipTrigger') tooltipTrigger: ElementRef;
this.showTooltip = false;

constructor( private renderer: Renderer2) {
  this.renderer.listen('window', 'click', (e: Event) => {
    if (this.showTooltip && e.target !== this.itemTooltip.nativeElement) {
      // never gets to here 
      console.log(‘click detected’);
      this.toggleTooltip();
    }
  });
}

toggleTooltip() {
  const tooltipStatus = this.showTooltip;
  if (tooltipStatus = true) {
    this.showTooltip = false;
  } else if (tooltipStatus = false) {
    this.showTooltip = true;
  }
}

Create a Directive in Common Place to access from anywhere, Add it to Module also for using Directive在公共位置创建一个指令以从任何地方访问,将其添加到模块也以使用指令

import {Directive, ElementRef, Output, EventEmitter, HostListener} from '@angular/core';
 
@Directive({
    selector: '[clickOutside]'
})
export class ClickOutsideDirective {
    constructor(private _elementRef : ElementRef) {
    }
 
    @Output()
    public clickOutside = new EventEmitter();
 
    @HostListener('document:click', ['$event.target'])
    public onClick(targetElement) {
        const clickedInside = this._elementRef.nativeElement.contains(targetElement);
        if (!clickedInside) {
            this.clickOutside.emit(null);
        }
    }
}

HTML HTML

<li *ngFor="let listItem of listItems;">
  <p>
    <span *ngIf="showTooltip" class="item-tooltip" #itemTooltip>
      Tooltip with {{ listItem.detailed }}
      <span (clickOutside )="closeTooltip()">Close</span>
    </span>
    <span (click)="openTooltip()" #tooltipTrigger>{{ listItem.blurb }}</span>
  </p>
</li>

TS TS

openTooltip = () => { showTooltip = true; }

clickOutside = () => { showTooltip = false; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM