2017-08-28 7 views
-1

Angular4コンポーネントでthisを取得したいと思いますが、Jqueryを使用しません。角4:マウスオーバレイでマウスオーバーレイを表示する

mouseoverとmouseoutの両方のマウスの向きに基づいて、オーバーレイのdivをアニメーションで表示する必要があります。コンポーネントのサンプルコードを書き直そうとしましたが、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 
    } 
} 

任意のアイデア?

は、私はあなたが各<div>のためにそれを「再利用」することができますDirectiveを書くために、より良いことだと思うあなた

+0

'console.log(this._el、nativeElement);'を試してみると、コードに '_el'がありません。 – Sasxa

+0

i console.log thisまたはthis._elの場合は、グローバルコンポーネントdivが表示されます。私はターゲット要素の幅を取得する必要があります。 – SBO

+0

'e.target'はすでにElementRefではないDOMノードです。 – cyrix

答えて

2

私はこの効果を好むので、私は角度アニメーションと成分からなる: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; 
    } 

} 
+0

デモにいくつか問題があります。 1つを他のものに速く移動すると、0.1秒に遷移時間を下げても、一部のオーバーレイはアクティブのままです。キューキューのマネージャーがいなくなっているとか、他のすべての要素をホバリングしたときに落ちる何らかのロジックだと思います。とにかく、良い仕事ありがとう! – SBO

+0

@SBO変更検出の問題です。カーソルを高速に移動すると、 'ExpressionChangedAfterItHasBeenCheckedError'エラーが発生します。私はそれが生産モードでは正常に動作すると思いますが、まだテストしていません... – Sasxa

+0

@SBOコードとデモを更新しました。オーバーレイが正しく削除されました。エラーはまだ開発モードでは発生しますが、実動モードではテストされません。 – Sasxa

1

ありがとうございます。

指令:

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

Plunker

+0

ディレクティブを使用しても、コンポーネント内で同じことを行うのはどうですか? – SBO

+0

DOMList要素へのアクセスがはるかに簡単なので、HostListenerはより良い解決策です。さらに、コンポーネントクラスからはやっていません。それ以外の場合は、テンプレート変数をdivに配置し、@viewchildを使用してアクセス権を取得します。 plunkerを更新しました – Vega

+0

問題は私がngforサイクルでこれを持っているので、動的テンプレート変数を生成し、いくつかの困難でそれらにアクセスすべきです。私は角度が新しく、別の解決策があるのか​​どうか疑問に思いましたが、あなたの方が良いと思われます。ありがとうございました! – SBO

関連する問題