我想在不使用Jquery的情况下在Angular4组件中获得this。
我需要根据鼠标方向显示带有动画的叠加div,包括mouseover和mouseout。我试图在我的组件中重写示例代码,但我无法获得event.target的宽度和高度。
我的div:
<div (mouseover)='showOverlay($event)'>div to hover</div>
组件:
export class MyComponent implements OnInit {
constructor(private _el: ElementRef) {
}
ngOnInit() {
}
showOverlay(e) {
const target = e.target;
console.log(target._el.nativeElement); // Returns undefined
console.log(target.nativeElement); // Returns undefined
console.log(target.nativeElement.width); // Error
console.log(target._el.nativeElement.width); // Error
}
}
有什么想法吗?
谢谢
答案 0 :(得分:7)
我喜欢这种效果,所以我制作了一个带角度动画的组件:https://stackblitz.com/edit/angular-fftwpg。
import { Component, HostListener } from '@angular/core';
import { AnimationEvent } from '@angular/animations';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
const animateIn = '0.15s ease-in';
const animateOut = '0.25s ease-out';
const styleIdle = { transform: 'translate3d(0, 0, 0)' };
const styleTop = { transform: 'translate3d(0, -100%, 0)' };
const styleRight = { transform: 'translate3d(100%, 0, 0)' };
const styleBottom = { transform: 'translate3d(0, 100%, 0)' };
const styleLeft = { transform: 'translate3d(-100%, 0, 0)' };
export const HoverContainerAnimations = [
trigger('hover', [
state('*', style(styleIdle)),
transition('* => in-left', [
style(styleLeft), animate(animateIn)
]),
transition('* => in-right', [
style(styleRight), animate(animateIn)
]),
transition('* => in-top', [
style(styleTop), animate(animateIn)
]),
transition('* => in-bottom', [
style(styleBottom), animate(animateIn)
]),
transition('* => out-right', [
animate(animateOut, style(styleRight))
]),
transition('* => out-left', [
animate(animateOut, style(styleLeft))
]),
transition('* => out-top', [
animate(animateOut, style(styleTop))
]),
transition('* => out-bottom', [
animate(animateOut, style(styleBottom))
]),
])
];
@Component({
// tslint:disable-next-line:component-selector
selector: 'hover-container',
template: `
<ng-content></ng-content>
<div class="overlay"
*ngIf="state"
[@hover]="state"
(@hover.done)="onDone($event)">
<ng-content select="[overlay]"></ng-content>
</div>`,
styleUrls: ['./hover-container.component.css'],
animations: HoverContainerAnimations,
})
export class HoverContainerComponent {
state;
@HostListener('mouseenter', ['$event'])
@HostListener('mouseleave', ['$event'])
onHover(event: MouseEvent) {
const direction = event.type === 'mouseenter' ? 'in' : 'out';
const host = event.target as HTMLElement;
const w = host.offsetWidth;
const h = host.offsetHeight;
const x = (event.pageX - host.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
const y = (event.pageY - host.offsetTop - (h / 2)) * (h > w ? (w / h) : 1);
const states = ['top', 'right', 'bottom', 'left'];
const side = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
this.state = `${direction}-${states[side]}`;
}
onDone(event: AnimationEvent) {
this.state = event.toState.startsWith('out-') ? null : this.state;
}
}
答案 1 :(得分:2)
我认为最好写一个Directive
,以便您可以为每个<div>
“重复使用”它。
<强>指令:强>
@Directive({
selector: '[over]'
})
export class OverDirective {
constructor(private elementRef: ElementRef) {
}
@HostListener('mouseover', ['$event'])
onOver(event: MouseEvent): void {
console.log(this.elementRef.nativeElement.offsetHeight)
}
}
<强> HTML 强>:
<div over id="myDiv">div to hover</div>
如果您仍想通过模板变量访问组件内部的元素:
<强> HTML 强>
<div id="div2" (mouseover)="onMouseOver($event, toto)" #toto>an other div to hover</div>
<强>打字稿强>
onMouseOver(event, elem)
{
console.log(elem.offsetHeight);
}