2017-11-25 6 views
0

가능한 경우 애니메이션 효과를 사용하여 목록에서 항목을 부드럽게 스크롤하는 방법을 찾는 중입니다. 항목의 내 목록과 같은 방법angular : 요소의 자동 스크롤

은 다음과 같습니다 https://plnkr.co/edit/nRhpyO71eHOaQTzOElFe?p=preview

<button (click)="prev()">Prev</button> 
<button (click)="next()">Next</button> 
<button (click)="autoplay()">Auto play</button> 
<div> 
    Current: {{current}} 
</div> 

<div class="wrapper"> 

    <mat-card *ngFor="let item of [0, 1, 2,3,4,5,6,7,8,9]" 
    class="item" id="'item'+item" 
    [ngClass]="item == current ? 'active' : ''" 
    > 
    This is item {{item}} 
    </mat-card> 

</div> 

구성 요소 -

export class CardOverviewExample { 

    constructor(private elRef:ElementRef) { 

    } 

    current: number = 0; 

    autoplay() { 
    if (this.current < 9) { 
    next(); 
    } else { 
     this.current = 0; 
    } 
    setTimeout(() => this.autoplay(), 2000); 
    } 

    next() { 
    this.current = this.current + 1; 
    setTimeout(() => this.scrollCurrentIntoView); 
    } 
    prev() { 
    this.current = this.current - 1; 
    setTimeout(() => this.scrollCurrentIntoView); 
    } 
    scrollCurrentIntoView() { 

    let id = '#item' + current; 
    let el = this.elRef.nativeElement.querySelector(id); 
    console.log("el: ", el); 
    el.nativeElement.scrollIntoView({behavior: "smooth", block: "start", inline: "start"}); 
    } 
} 

다음 요소로 이동하는 수동 모드를 모두 거기와 다음 항목이 될 경우 자동 모드가있다 몇 초 후에 활성화됩니다. 요구 사항은 항상 현재 활성 요소를 맨 위에 놓고 사용자가 목록에서 다른 항목을 선택하려는 경우 여전히 목록을 스크롤하는 것입니다.

나는 scrollIntoView를 사용하여 동작을 시도해 보았습니다. 작동하지만, 때로는 화려하고 대안을 찾고 있습니다. (참고 : scrollIntoView는 plunker 예제에서는 작동하지 않지만 내 애플 리케이션에서 작동합니다).

https://stackoverflow.com/a/45367387/1893487에서 제안한 해결책을 시도했습니다. 슬로우 스크롤을 시뮬레이트하기 위해 scrollTop 값을 2 이상 다른 증분으로 설정해 보았습니다. 이것은 효과가 있지만 여전히 부드럽 지 않습니다. 때로는 각도 변화 검출기가 중간 상태를 나타내는 것을 보지 못합니다.

CSS translateY transform을 사용하여 스크롤링을 달성 할 수 있는지 궁금합니다. 스크롤링이 더 효율적이기도합니다. 스크롤링을 구현하기위한 대체 메커니즘에 대한 제안을 환영합니다.

답변

0

당신은 조금 JS를 사용할 수

function currentYPosition() { 
// Firefox, Chrome, Opera, Safari 
if (self.pageYOffset) return self.pageYOffset; 
// Internet Explorer 6 - standards mode 
if (document.documentElement && document.documentElement.scrollTop) 
    return document.documentElement.scrollTop; 
// Internet Explorer 6, 7 and 8 
if (document.body.scrollTop) return document.body.scrollTop; 
return 0; 
}; 

function elmYPosition(eID) { 
    var elm = document.getElementById(eID); 
    var y = elm.offsetTop; 
    var node = elm; 
    while (node.offsetParent && node.offsetParent != document.body) { 
     node = node.offsetParent; 
     y += node.offsetTop; 
    } return y; 
}; 

function smoothScroll(eID) { 
    var startY = currentYPosition(); 
    var stopY = elmYPosition(eID); 
    var distance = stopY > startY ? stopY - startY : startY - stopY; 
    if (distance < 100) { 
     scrollTo(0, stopY); return; 
    } 
    var speed = Math.round(distance/75); 
    if (speed >= 20) speed = 20; 
    var step = Math.round(distance/25); 
    var leapY = stopY > startY ? startY + step : startY - step; 
    var timer = 0; 
    if (stopY > startY) { 
     for (var i=startY; i<stopY; i+=step) { 
      setTimeout("window.scrollTo(0, "+leapY+")", timer * speed); 
      leapY += step; if (leapY > stopY) leapY = stopY; timer++; 
     } return; 
    } 
    for (var i=startY; i>stopY; i-=step) { 
     setTimeout("window.scrollTo(0, "+leapY+")", timer * speed); 
     leapY -= step; if (leapY < stopY) leapY = stopY; timer++; 
    } 
    return false; 
}; 

다음이

scrollCurrentIntoView() { 

let id = '#item' + current; 
let el = this.elRef.nativeElement.querySelector(id); 
console.log("el: ", el); 
smoothScroll(el); 

}

처럼보기에 스크롤을 변경