在Angular 2中自动滚动
Autoscroll in Angular 2
我在Angular 2中遇到一个问题,从一条路线更改到另一条路线不会自动滚动到新视图的顶部。我意识到Angular 1允许将autoscroll
属性添加到HTML元素中,而其他人则想出了一些简单的javascript(如window.scroll(0, 0)
)来强制视图在加载时滚动到顶部。
然而,我不确定如何使用Angular 2来实现这一点。有人知道如何做到这一点吗?
更新
目前还没有自动的方法。
另请参阅Angular 2在新路由器上使用订阅功能时的打字错误(rc 1)
另请参阅https://github.com/angular/angular/issues/6595#issuecomment-244232725
class MyAppComponent { constructor(router: Router) { router.events.subscribe(s => { if (s instanceof NavigationEnd) { const tree = router.parseUrl(router.url); if (tree.fragment) { // you can use DomAdapter const element = document.querySelector("#" + tree.fragment); if (element) { element.scrollIntoView(element); } } } }); } }
更新
在新的路由器V3测试版2中,您可以传递带有路由器链接和路由器导航的片段
<a [routerLink]="..." fragment="top">
它应该滚动到它,但也将#top
添加到URL(我自己还没有测试)
更新
原始
这是一个悬而未决的问题https://github.com/angular/angular/issues/6595
解决方法(在https://github.com/angular/angular/issues/6946)
注入路由器,订阅路由更改并调用滚动到顶部:
>=RC.x
router.changes.subscribe() => {
window.scrollTo(0, 0);
});
β
router.events
.filter(e => e instanceof NavigationEnd)
.subscribe(() => {
window.scrollTo(0, 0);
});
您可以在这里看到吗:https://angular.io/docs/ts/latest/api/router/index/Router-class.html##事件锚点,您必须使用"router.events.subscribe",因为Angular 2.0.0
因此,自动搜索到所有页面顶部的一个好的解决方案是拥有这样的AppComponent:
import {Component} from '@angular/core';
import {Router, NavigationEnd} from "@angular/router";
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor(private router: Router) {
router.events.subscribe((val) => {
if (val instanceof NavigationEnd){
window.scrollTo(0,0);
}
});
}
}
较新的RC(>=RC.3)似乎没有公开changes
Observable,它可能已经被重命名为events或routerEvents。
他们完全"神奇"的医生似乎没有提供任何关于正在做什么的信息,所以我想你会在那里玩一点俄罗斯轮盘赌。或者扔硬币什么的。
从这个答案来看,events
Observable似乎返回了有关导航状态的事件:
router.events.subscribe(event:Event => { if(event is NavigationStart) { } // NavigationEnd // NavigationCancel // NavigationError // RoutesRecognized }
我遇到了同样的问题。根据Gunter的回答,我发现Angular的2 RC.1新路由器并没有直接暴露Observable。相反,它具有用于该目的的changes
属性。RC.1的变通方法是:
this._router.changes.subscribe(() => {
window.scrollTo(0, 0);
});
我在每个页面的ngOnInit中使用了if(this.router.navigationd)来确定是否使用window.sollTo(0,0)。这将涵盖大多数路由到页面的情况,同时如果单击浏览器的"后退"按钮,则将滚动位置保留在该位置。
if(this.router.navigated) {
window.scrollTo(0, 0);
}
我测试的100%溶液:
constructor(router:Router){
this.router.events.subscribe(() => {
window.scrollTo(0, 0);
});
}
我在问题线程中发布了这篇文章,但我会在这里再次发布。
我的团队一直在angular.io上使用angular团队在这个repo上使用的东西。只需像往常一样提供服务并注入即可。然后,在每个页面上的ngAfterViewInit上,只要调用此行为即可。[scroll service variable name]scrollToTop()。最后,您需要将其添加到index.html:<div id="top-of-page"></div>
中<body>
的顶部
服务代码:
import { Injectable, Inject } from '@angular/core';
import { PlatformLocation } from '@angular/common';
import { DOCUMENT } from '@angular/platform-browser';
import {fromEvent} from 'rxjs/observable/fromEvent';
export const topMargin = 16;
/**
* A service that scrolls document elements into view
*/
@Injectable()
export class ScrollService {
private _topOffset: number | null;
private _topOfPageElement: Element;
// Offset from the top of the document to bottom of any static elements
// at the top (e.g. toolbar) + some margin
get topOffset() {
if (!this._topOffset) {
const toolbar = this.document.querySelector('md-toolbar.app-toolbar');
this._topOffset = (toolbar && toolbar.clientHeight || 0) + topMargin;
}
return this._topOffset;
}
get topOfPageElement() {
if (!this._topOfPageElement) {
this._topOfPageElement = this.document.getElementById('top-of-page') || this.document.body;
}
return this._topOfPageElement;
}
constructor(
@Inject(DOCUMENT) private document: any,
private location: PlatformLocation) {
// On resize, the toolbar might change height, so "invalidate" the top offset.
fromEvent(window, 'resize').subscribe(() => this._topOffset = null);
}
/**
* Scroll to the element with id extracted from the current location hash fragment.
* Scroll to top if no hash.
* Don't scroll if hash not found.
*/
scroll() {
const hash = this.getCurrentHash();
const element: HTMLElement = hash
? this.document.getElementById(hash)
: this.topOfPageElement;
this.scrollToElement(element);
}
/**
* Scroll to the element.
* Don't scroll if no element.
*/
scrollToElement(element: Element) {
if (element) {
element.scrollIntoView();
if (window && window.scrollBy) {
// Scroll as much as necessary to align the top of `element` at `topOffset`.
// (Usually, `.top` will be 0, except for cases where the element cannot be scrolled all the
// way to the top, because the viewport is larger than the height of the content after the
// element.)
window.scrollBy(0, element.getBoundingClientRect().top - this.topOffset);
// If we are very close to the top (<20px), then scroll all the way up.
// (This can happen if `element` is at the top of the page, but has a small top-margin.)
if (window.pageYOffset < 20) {
window.scrollBy(0, -window.pageYOffset);
}
}
}
}
/** Scroll to the top of the document. */
scrollToTop() {
this.scrollToElement(this.topOfPageElement);
}
/**
* Return the hash fragment from the `PlatformLocation`, minus the leading `#`.
*/
private getCurrentHash() {
return this.location.hash.replace(/^#/, '');
}
}
对于那些发现window.scrollTo(0,0)
不起作用的人(我猜是因为材料设计侧面导航,但完全是猜测),请使用这里的方法:Javascript/CSS窗口.scrollTo(0,0)不工作
我正在使用material sidenav,但我无法获得任何建议的答案。以下是我的工作解决方案:
import { Router, NavigationEnd } from '@angular/router';
...
constructor(
private router: Router,
) {
router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
document.querySelector('.mat-sidenav-content').scrollTop = 0;
}
}
}
我没有在每个组件中编写代码,而是在一个地方添加了以下代码-
<router-outlet (activate)="onActivate($event)"></router-outlet>
onActivate(e) {
window.scrollTo(0, 0);
}
- 如何在Angular JS中滚动显示元素
- 滚动指令在Angular JS中不起作用
- 如何在滚动时将jQuery fadeIn添加到Angular应用程序中
- Chrome标签或书签滚动会影响angular应用程序
- Angular Material,侧边栏中的列表不可滚动
- Angular UI Grid重用的网格无法重置滚动+无限滚动无法工作
- 如何在angular js中使用滚动条打印iframe内容
- Angular Material md工具栏未粘贴(md滚动收缩)
- 在Angular 2中自动滚动
- Angular js 避免在用户无限滚动和删除 dom 元素时重复数据
- 使用 Ionic 的 Angular JS 无限滚动问题
- angular:绑定到滚动事件不起作用
- Angular ui路由器在特定状态下自动滚动
- angular js设置动画以滚动到视口顶部
- 在Angular应用程序中初始加载时滚动容器
- angular渲染元素后滚动到列表项
- Angular JS在重新加载后保留滚动位置
- 检测Angular JS中滚动到文档结尾的实现
- Ionic Angular JS$routeProvider加载离子列表获胜't滚动
- 在Ionic/Angular中向下滚动时隐藏子标题