Angular2, HostListener, how can I target an element? can I target based on class?

后端 未结 8 1141
后悔当初
后悔当初 2020-12-05 01:50

In Angular2, how can I target an element within the HostListener decorator?

@HostListener(\'dragstart\', [\'$event\'])
    onDragStart(ev:Event) {
        co         


        
相关标签:
8条回答
  • 2020-12-05 02:30
    import { Directive, ElementRef, OnInit, Output, EventEmitter} from '@angular/core';
    
        @Directive({
              selector: '[checkClick]'
            })
    
            export class checkClickDirective implements OnInit {
    
            @Output() public checkClick = new EventEmitter();
    
            constructor(private _el: ElementRef) { }
    
            @HostListener('click', ['$event.target']) public onClick(targetElement) {
    
                const checkClick = this._el.nativeElement.contains(targetElement);
    
                (checkClick)?this.checkClick.emit(true):this.checkClick.emit(false);
              }
            }
    
    0 讨论(0)
  • 2020-12-05 02:41

    As pointed out by Googs, the accepted answer does answer the question but doesn't help find a solution.

    I built upon alex's answer as I needed a way to use the functionality I already had in my @HostListener for retrieving a list of notifications for different screen sizes.

    For example, in my app - the notifications page has its own route on mobile but existed in the sidebar on tablet and screen sizes above, so I couldn't use the @HostListener there as it would only trigger when I hit the bottom of the whole page and not the sidebar.

    Instead I looked up the <div> I was interested in and attached what I needed. So the following code:

    attachListenerToContainer() {
        let elementToListenTo = this.ele ? this.ele : 'window';
    
        this.renderer.listen(elementToListenTo, 'scroll', (event) => {
          if(!this.reachedBottom) {
            if((getHeight(this.ele) + getScrollTop(this.ele)) >= getOffset(this.ele)) {
              this.reachedBottom = true;
              this.getNextNotificationsPage();
            }
          }
        });
    
        function getScrollTop(ele) {
          return ele ? ele.scrollTop : window.scrollY;
        }
        function getHeight(ele) {
          return ele ? ele.clientHeight : window.innerHeight;
        }
        function getOffset(ele) {
          return ele ? ele.scrollHeight : document.body.offsetHeight;
        }
      }
    

    The this.ele is the container div I'm interested in which I look up in the ngAfterViewInit() lifecycle hook for tablet and above. If I can't find that element then I use the window instead - effectively emulating the @HostListener

    Also - here's how I was looking up, in my case, the container element I wanted:

    this.ele = document.getElementsByClassName('notifications')[0]; 
    
    0 讨论(0)
  • 2020-12-05 02:44

    Since the accepted answer doesn't actually help to solve the problem, here is a solution.

    A better way to achieve this is by creating a directive, this way you can add the directive to any element you wish, and the listeners will only trigger for this particular element.

    For example:

    @Directive({
       selector: "[focus-out-directive]"
    })
    export class FocusOutDirective {
       @Output() onFocusOut: EventEmitter<boolean> = new EventEmitter<false>();
    
       @HostListener("focusout", ["$event"])
       public onListenerTriggered(event: any): void {
           this.onFocusOut.emit(true);
       }
    }
    

    Then on your HTML elements you wish to apply this listener to, just add the directive selector, in this case focus-out-directive, and then supply the function you wish to trigger on your component.

    Example:

    <input type='text' focus-out-directive (onFocusOut)='myFunction($event)'/>

    0 讨论(0)
  • 2020-12-05 02:44

    Listen on an element:

    import { Renderer2 } from '@angular/core';
    ...
    constructor(private renderer: Renderer2) {}
    
    // Get this.myElement with document.getElement... or ElementRef 
    
    ngOnInit() {
      // scroll or any other event
      this.renderer.listen(this.myElement, 'scroll', (event) => {
      // Do something with 'event'
      console.log(this.myElement.scrollTop);
    });
    

    }

    0 讨论(0)
  • 2020-12-05 02:48

    @HostListener() only supports window, document, and body as global event targets, otherwise it only supports the components host element.

    0 讨论(0)
  • 2020-12-05 02:48

    in component template

    <div (event)="onMouseEnter()">
        <p>United States of America (mouseenter)</p>
    </div>
    
    <div (event)="onMouseOut()">
        <p>United States of America (mouseout)</p>
    </div>
    

    in class component

    import { Component, OnInit, HostListener } from '@angular/core';
    
    @Component({
      selector: 'app-simpleevent',
      templateUrl: './simpleevent.component.html',
      styleUrls: ['./simpleevent.component.css']
    })
    export class SimpleeventComponent implements OnInit {
      @HostListener("mouseenter", ["$event"]) onMouseEnter(event: Event) {
        console.log(event.type);
      }
    
      @HostListener("mouseout", ["$event"]) onMouseOut(event: Event) {
        console.log(event.type);
        console.log(event.target)
      }
      constructor() { }
    
      ngOnInit() {
      }
    }
    
    0 讨论(0)
提交回复
热议问题