2017-07-19 5 views
23

私はフルページ幅/高さdivを持つウェブページを作成しています。 スクロールしながら、私は2種類の方法を持っています。 HostListenerスクロールアニメーション効果を追加する方法角4 - スクロールアニメーション

@HostListener("window:scroll", ['$event']) 
    onWindowScroll($event: any): void { 
    this.topOffSet = window.pageYOffset; 
    //window.scrollTo(0, this.topOffSet+662); 
    } 

1.上

スクロールクリックで

//HTML 
<a (click)="goToDiv('about')"></a> 

//JS 
    goToDiv(id) { 
     let element = document.querySelector("#"+id); 
     element.scrollIntoView(element); 
     } 

スクロール?

だけのよう:

$('.scroll').on('click', function(e) { 
    $('html, body').animate({ 
     scrollTop: $(window).height() 
    }, 1200); 
}); 

2.そして、どのように次のdivにスクロールするHostListenerを使用するには?

+0

私はそれがここの解決だと思う。 [https://stackoverflow.com/questions/38748572/scroll-event-on-hostlistener](https://stackoverflow.com/questions/38748572/scroll-event-on-hostlistener ) –

+0

@ObaidulHaque 'HostListener'が正しく動作しています。アニメーションを追加する方法がわかりません。 –

+0

ホストリスナーで呼び出す関数でCSSアニメーションを使用します。ここの良いガイド:https://css-tricks.com/aos-css-driven-scroll-animation-library/ –

答えて

8

これは楽しいです。この解は、角度2の大部分のものと同様に、観測可能です。

getTargetElementRef(currentYPos: int): ElementRef { 
     // you need to figure out how this works 
     // I can't comment much on it without knowing more about the page 
     // but you inject the host ElementRef in the component/directive constructor and use normal vanillaJS functions to find other elements 
    } 
    //capture the scroll event and pass to a function that triggers your own event for clarity and so you can manually trigger 
    scrollToSource: Subject<int> = new Subject<int>(); 
    @HostListener("window:scroll", ['$event']) 
    onWindowScroll($event: any): void { 
    var target = getTargetElementRef(window.pageYOffset); 
    this.scrollTo(target); 
    } 

    scrollTo(target: ElementRef): void { 
    // this assumes you're passing in an ElementRef, it may or may not be appropriate, you can pass them to functions in templates with template variable syntax such as: <div #targetDiv>Scroll Target</div> <button (click)="scrollTo(targetDiv)">Click To Scroll</button> 
    this.scrollToSource.next(target.nativeElement.offsetTop); 
    } 

    //switch map takes the last value emitted by an observable sequence, in this case, the user's latest scroll position, and transforms it into a new observable stream 
    this.scrollToSource.switchMap(targetYPos => { 
     return Observable.interval(100) //interval just creates an observable stream corresponding to time, this emits every 1/10th of a second. This can be fixed or make it dynamic depending on the distance to scroll 
      .scan((acc, curr) => acc + 5, window.pageYOffset) // scan takes all values from an emitted observable stream and accumulates them, here you're taking the current position, adding a scroll step (fixed at 5, though this could also be dynamic), and then so on, its like a for loop with +=, but you emit every value to the next operator which scrolls, the second argument is the start position 
      .do(position => window.scrollTo(0, position)) /// here is where you scroll with the results from scan 
      .takeWhile(val => val < targetYPos); // stop when you get to the target 
    }).subscribe(); //don't forget! 

これは使いやすいです。クリックするだけでscrollToをバインドします

これは、一方向のスクロールにのみ有効ですが、これはあなたを始めにするはずです。スキャンをよりスマートにして、上がる必要がある場合は減算し、上または下に移動する場合に基づいて正しい終了条件を把握する関数をtakeWhile内で使用します。

+0

あなたのコードは私にとって素晴らしい、ありがとう。ちょうど追加すると、角度4>のためにあなたはインポート '' rxjs/add/operator/switchMap ';を使う必要があります。そうでなければ "..switchMapは関数ではありません"という問題に直面します。 – KeaganFouche