我想找到一种方法让列表中的项目顺利向上滚动,如果可能的话会产生动画效果。
以下是我的商品清单: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的行为:smooth。虽然它有效,但它有时会浮华,我正在寻找替代品。 (注意:scrollIntoView并不适用于plunker示例,但它适用于我的应用程序。)
我尝试了在https://stackoverflow.com/a/45367387/1893487建议的解决方案 - 模拟慢速滚动我尝试将scrollTop值设置为2s以上的不同增量。这样可行,但它仍然不顺畅。有时我看不到角度变化检测器显示中间状态。
我想知道是否有可能使用CSS translateY转换来实现滚动,因为这也应该更高效。建议实现滚动的替代机制。
答案 0 :(得分: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);
}