In Angular2, how can I target an element within the HostListener decorator?
@HostListener(\'dragstart\', [\'$event\'])
onDragStart(ev:Event) {
co
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);
}
}
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];
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)'/>
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);
});
}
@HostListener()
only supports window
, document
, and body
as global event targets, otherwise it only supports the components host element.
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() {
}
}