简体   繁体   English

HostListener和event.target

[英]HostListener and event.target

Good Morning, I've strange problem, I tried to find a solution, but I didn't ;/ I have a 3 anchor elements with the class 'navi-start' each as below. 早上好,我有一个奇怪的问题,我试图找到一个解决方案,但是我没有找到; /我有3个锚元素,每个锚元素的类为“ navi-start”,如下所示。

 <a class="navi-start test-class"><i class="fab fa-accessible-icon"></i>x</a>
  <a class="navi-start"><i class="fab fa-accessible-icon"></i>y</a>
  <a class="navi-start"><i class="fab fa-accessible-icon"></i> z</a>

By the @HostListener I'd like to 'listen' clicks on the anchor elements. 通过@HostListener,我想“监听”锚元素上的单击。 I used event.target as Element and it works almost perfectly. 我使用event.target作为元素,它几乎完美地工作。 Problems begin to appear when I'm clicking on the icon element. 当我单击图标元素时,问题开始出现。 event.target returns me !document. event.target返回我的文档!

  @HostListener('document:click', ['$event'])


CheckClick(event) {
    const targetElement = event.target as Element;
    const textElement = targetElement.textContent;
    const query = document.querySelector('.test-class');

if (targetElement.classList.contains('navi-start')) {

  this.rend.removeClass(query, 'test-class');
  this.rend.addClass(targetElement, 'test-class');
  if (textElement === 'x') {
    this.router.navigate(['main']);
  }
  else if (textElement === 'y') {
    this.router.navigate(['main/parts']);
  }
  else {
    this.router.navigate(['main/motorcycle']);
  }
}
else console.log(targetElement);

} }

and console.log(targetElement) returns me just icon element. 和console.log(targetElement)仅返回图标元素。 Could someone tell me how to solve my problem? 有人可以告诉我如何解决我的问题吗?

It would seem that you are listening for clicks in the entire document by 看来您正在侦听整个文档中的点击

@HostListener('document:click' ...

I would recommend trying to narrow the scope, perhaps listening for 'click' instead if possible, this would limit the listener to the element the directive was put on. 我建议尝试缩小范围,如果可能的话,也许监听'click',这会将监听器限制为放置该指令的元素。

your function will receive the click events. 您的函数将收到点击事件。 The target for each of those events will be the actual element that was clicked, therefor you will get icon if you click on the icon. 这些事件中的每一个的目标都将是被单击的实际元素,因此,如果单击图标,您将获得图标。

what you could do is check if the element matches what you expect and if not traverse the dom to find a matching parent. 您可以做的是检查元素是否符合您的期望,如果不遍历dom来找到匹配的父对象。 thus capturing the click inside the expected target. 从而在预期目标内捕获点击。 so if you click the icon you will still get a match on the anchor tag. 因此,如果您单击该图标,您仍会在锚标记上找到匹配项。 like so: 像这样:

CheckClick(event) {
    let targetElement = event.target as Element; //changed to let
    const textElement = targetElement.textContent;
    const query = document.querySelector('.test-class');

    if (!targetElement.matches('.navi-start')) { //if clicked element doesn't have class '.navi-start'
      targetElement = targetElement.closest('.navi-start') as Element; // find parent that has class 'navi-start'
    }
    if (targetElement) { //if targetElement of type 'navi-start' was found
      this.rend.removeClass(query, 'test-class');
      this.rend.addClass(targetElement, 'test-class');
      if (textElement === 'x') {
        this.router.navigate(['main']);
      }
      else if (textElement === 'y') {
        this.router.navigate(['main/parts']);
      }
      else {
        this.router.navigate(['main/motorcycle']);
      }
    }
    else {
      console.log(targetElement);
    }
}

Anyway I found easiest way just by using Angular directives without any methods. 无论如何,我发现最简单的方法就是使用没有任何方法的Angular指令。

<a class="navi-start" [routerLink]="['/main']"  routerLinkActive="test-class" [routerLinkActiveOptions]="{ exact: true }"><i class="fab fa-accessible-icon" ></I>x</a>
  <a class="navi-start" routerLink="parts"  routerLinkActive="test-class"><i class="fab fa-accessible-icon" ></i>y</a>
  <a class="navi-start" routerLink="motorcycle"  routerLinkActive="test-class"><i class="fab fa-accessible-icon" ></i>z</a>

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

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