Angular 角度4:使用基于鼠标方向的动画在鼠标上方显示覆盖

Angular 角度4:使用基于鼠标方向的动画在鼠标上方显示覆盖,angular,Angular,我希望在不使用Jquery的情况下使用Angular4组件 我需要显示一个叠加div,动画基于鼠标方向,包括mouseover和mouseout。我试图在我的组件中重写示例代码,但无法获得event.target的宽度和高度 我的部门: <div (mouseover)='showOverlay($event)'>div to hover</div> export class MyComponent implements OnInit { constructo

我希望在不使用Jquery的情况下使用Angular4组件

我需要显示一个叠加div,动画基于鼠标方向,包括mouseover和mouseout。我试图在我的组件中重写示例代码,但无法获得event.target的宽度和高度

我的部门:

<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
    }
}
@Directive({
    selector: '[over]'
})
export class OverDirective {
    constructor(private elementRef: ElementRef) {
    }

    @HostListener('mouseover', ['$event'])
    onOver(event: MouseEvent): void {
        console.log(this.elementRef.nativeElement.offsetHeight)
    }
}
有什么想法吗


谢谢

我认为最好编写一个
指令
,这样您就可以对每个
进行“重用”

指令:

<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
    }
}
@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>

我喜欢这个效果,所以我制作了一个带有角度动画的组件:

从'@angular/core'导入{Component,HostListener};
从'@angular/animations'导入{AnimationEvent};
进口{
触发
国家,,
风格
使有生气
过渡
}来自“@angular/animations”;
常数animateIn='0.15s慢进';
常数animateOut='0.25s缓解';
constyleidle={transform:'translate3d(0,0,0)');
constyletop={transform:'translate3d(0,-100%,0)};
constyleright={transform:'translate3d(100%,0,0)};
constylebottom={transform:'translate3d(0,100%,0)};
constyleleft={transform:'translate3d(-100%,0,0)};
导出常量hoverContainerImations=[
触发器('悬停'[
状态('*',样式(styleIdle)),
过渡('*=>在左'[
样式(styleLeft)、动画(animateIn)
]),
过渡('*=>在右侧'[
样式(styleRight)、动画(animateIn)
]),
过渡('*=>在顶部'[
样式(styleTop)、动画(animateIn)
]),
过渡('*=>在底部'[
样式(styleBottom)、动画(animateIn)
]),
过渡('*=>out right'[
动画(动画输出、样式(样式右侧))
]),
过渡('*=>out left'[
动画(动画输出,样式(样式左))
]),
过渡('*=>Outtop'[
动画(动画输出、样式(样式顶部))
]),
过渡('*=>out bottom'[
动画(动画输出、样式(样式底部))
]),
])
];
@组成部分({
//tslint:禁用下一行:组件选择器
选择器:“悬停容器”,
模板:`
`,
样式URL:['./hover container.component.css'],
动画:悬停容器动画,
})
导出类HoverContainerComponent{
国家;
@HostListener('mouseenter',['$event']))
@HostListener('mouseleave',['$event']))
onHover(事件:MouseEvent){
const direction=event.type=='mouseenter'?'in':'out';
const host=event.target作为HTMLElement;
const w=host.offsetWidth;
const h=主机。离视;
常量x=(event.pageX-host.offsetLeft-(w/2))*(w>h?(h/w):1);
常数y=(event.pageY-host.offsetTop-(h/2))*(h>w?(w/h):1);
常量状态=[“顶部”、“右侧”、“底部”、“左侧”];
常数边=数学圆(((数学atan2(y,x)*(180/数学PI))+180)/90)+3)%4;
this.state=`${direction}-${states[side]}`;
}
OnOne(事件:AnimationEvent){
this.state=event.toState.startsWith('out-')?null:this.state;
}
}

Try
console.log(this.\el,nativeElement),您的代码中缺少
\u el
;如果我是console.log this或this。它会给我全局组件div。我需要获取目标元素的宽度。
e.target
已经是DOM节点而不是ElementRef。那么我需要做什么?e、 target.nativeElement返回undefinedWith directives work,但是在组件中执行相同的操作怎么样?HostListener是一个更好的解决方案,因为它更容易访问DOM元素。另外,您不需要从组件类执行此操作。否则,其中一种方法是在div上放置一个模板变量,并使用@viewchild获得访问权限。更新了Plunkers。问题是我在ngfor循环中有这个,所以应该生成动态模板变量,并在访问它们时遇到一些困难。我是个新手,我想知道是否还有其他解决方案,但你的解决方案似乎更好。非常感谢。ngfor中的每个div都将获得自己的hostlistner实例,每个div都将为您提供itYes的高度,这是使用指令。但是使用模板变量怎么样?你的演示有一些问题。即使将过渡时间降低到0.1s,如果您从一个快速移动到另一个,某些覆盖仍保持活动状态。我认为缺少一个queuque管理器,或者当一个元素悬停时,其他元素都会崩溃。不管怎样,干得好,谢谢@SBO这是一个更改检测问题,当您快速移动光标时,会发生
表达式更改TerithasBeenCheckedError
错误。我认为它在生产模式下可以正常工作,但还没有测试…@SBO我更新了代码和演示。覆盖层现在已正确删除。错误仍然在开发模式下抛出,但在生产模式下没有抛出(已测试)。类型“AnimationEvent”上不存在属性“toState”