我正在尝试检测何时在我的Angular 4应用程序中滚动窗口,但是当将onscroll
事件直接附加到<body>
时,事件似乎无法触发元素,或在我的组件中沿着这些行使用某些东西:
this.eventSubscription = Observable.fromEvent( winRef.nativeWindow, "scroll" ).subscribe( e => {
// do something
} );
网上有各种各样的帖子,但似乎并不是一个明确的答案。一篇文章建议,如果组件在Native
范围内,则必须在父元素上将封装设置为<router-outlet>
。我试过这个:没有工作,它毁了我的材料组件。
我的组件模板如下所示:
<!-- home.component.html -->
<div>
<p *ngFor="let item of playlistItems$ | async">
{{ item | json }}
</p>
</div>
组件本身:
// home.component.ts
@Component( {
selector: 'beyond-home',
templateUrl: './home.component.html',
styleUrls: [ './home.component.scss' ]
} )
export class HomeComponent {
playlistItems$: Observable<Array<IPlaylistItem>>;
eventSubscription;
constructor( private store: Store<fromRoot.IState>, private winRef: WindowRef ) {
this.store.dispatch( playlist.loadPlaylist() );
this.playlistItems$ = this.store.select( fromRoot.getPlaylistItems );
this.eventSubscription = Observable.fromEvent( winRef.nativeWindow, "scroll" ).subscribe( e => {
// do something
} );
}
}
我的生活不能解决正在发生的事情。事件并没有被解雇!我正在使用Material 2,这可能会增加复杂性。我甚至订阅了正确的活动吗?真的是window:scroll
吗?我有错误的结束吗?
答案 0 :(得分:0)
我认为在您的代码中您只需要:
@HostListener('window:scroll', ['$event'])
onScroll(event) {
console.log('You scrolled!');
}
将此添加到组件对我有用。注意添加到正文可能不起作用,因为它不是您的应用程序的一部分。我也在使用材料,并且没有上述代码的副作用。
在这里查看plunkr:
您需要显示控制台,以便查看结果。
答案 1 :(得分:0)
尝试异步加载表条目时遇到了同样的问题。最后,使用指令捕获滚动事件工作得很好,它也是可重用的。我没有在&lt; body&gt;上使用它但我猜测如果你把所有东西都包在一个&lt; div&gt;并在那里应用指令它将工作正常。这是我的指示:
import { Directive, HostListener, Output, EventEmitter } from
'@angular/core';
@Directive({
selector: '[rzScrollTracker]'
})
export class ScrollTrackerDirective {
@Output() updateLoad: EventEmitter<any> = new EventEmitter();
previousValue = 0;
scrollDir: string = undefined;
@HostListener('scroll', ['$event'])
onScroll(event) {
const tracker = event.target;
if(tracker.scrollTop > this.previousValue) {
this.scrollDir = 'down';
} else {
this.scrollDir = 'up';
}
// console.log('scrollDir:', this.scrollDir);
let limit = tracker.scrollHeight - tracker.clientHeight;
// console.log(event.target.scrollTop, limit);
if (event.target.scrollTop === limit) {
// console.log('end reached');
this.updateLoad.emit(true);
}
else if (event.target.scrollTop <= Math.floor(limit / 8) && this.scrollDir === 'up') {
// console.log('scrolled to top');
this.updateLoad.emit(false);
}
this.previousValue = tracker.scrollTop;
}
constructor() { }
}
我也在跟踪卷轴的方向,但你不必这样做。 然后,您可以在任何其他元素/组件上使用该指令。我在tbody元素和div上成功使用了它:
<tbody rzScrollTracker (updateLoad)="updateLoadFactor(nestedFilter, $event)"
<tr *ngFor="let row of filteredResultsInView[nestedFilter]['values']; let j = index">
<div class="checkbox">
<input type="checkbox"
[value]="row.toString()"
[disabled]="!areEnabledFromView[nestedFilter]"
id="checkrads_{{nestedFilter}}_{{i}}_{{j}}"
[checked]="selectedResultsObj[nestedFilter][row.toString()]"
#cbox
(click)="selectClickedElement(nestedFilter, cbox)">
<label for="checkrads_{{nestedFilter}}_{{i}}_{{j}}">{{ row.toString() }}</label>
</div>
</tr>
<tr> </tr>
<tr *ngIf="resultsInProgress[nestedFilter]">
Fetching results...
</tr>
</tbody>
指令发出的'updateLoad'事件在组件中捕获,并调用函数来修改显示的数据。我希望这有帮助!