我正在尝试对同一页面上的锚元素进行简单的滚动。基本上,该人点击“试一试”按钮,它会滚动到页面下方的区域,其ID为“登录”。现在,它正在使用基本的id="login"
&amp; <a href="#login"></a>
但它跳到那个部分。理想情况下,我希望它滚动到那里。如果我使用的是Angular4,是否有一些内置方法可以做到这一点或者最简单的方法是什么?谢谢!
整个模板......(组件仍为空)
<div id="image-header">
<div id="intro">
<h1 class="text-center">Welcome to ThinkPlan</h1>
<h3 class="text-center">Planning your way</h3>
<a class="btn btn-outline-primary" href="#login" id="view">Try It</a> <!-- Where the user clicks to scroll -->
</div>
</div>
<div class="container" id="info">
<div class="row">
<div class="col-md-12">
<div class="space" id="login"></div> <!-- The place to scroll to -->
<h1 class="text-center">ThinkPlan</h1>
<form class="form-horizontal">
<fieldset>
<legend>Login</legend>
<div class="form-group">
<label for="inputEmail" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="inputEmail" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-lg-2 control-label">Password</label>
<div class="col-lg-10">
<input type="password" class="form-control" id="inputPassword" placeholder="Password">
</div>
</div>
<div class="form-group" id="log-btn">
<div class="col-lg-10 col-lg-offset-2">
<button routerLink="/plan" type="submit" class="btn btn-outline-primary">Login</button>
</div>
</div>
<p class="lead text-center">New here? <a routerLink="signup">Sign up.</a></p>
</fieldset>
</form>
</div>
</div>
</div>
答案 0 :(得分:8)
自Angular v6起,anchorScrolling
有新的RouterModule
选项。您可以在模块的导入中进行设置:
imports: [
...,
RouterModule.forRoot(routes, {anchorScrolling: 'enabled'})
有了这个,Angular将自动滚动到具有给定片段ID的元素。
⚠️但是,这在异步加载数据时不起作用,请参阅此Github issue。 ⚠️
Smooth scrolling尚无法通过RouterModule
进行,但是您可以手动进行:
1)获得目标,例如与ViewChild
:
@ViewChild('pageInfo') pageInfo: ElementRef;
2)在scrollIntoView
上致电nativeElement
:
const targetElement = this.pageInfo.nativeElement
targetElement.scrollIntoView({behavior: "smooth"})
答案 1 :(得分:3)
使用Angular 4,您可以在使用锚点到同一页面时遇到一些问题。
我用这种方式解决了
安装
npm install ng2-page-scroll --save
导入app.module.ts
import {Ng2PageScrollModule} from 'ng2-page-scroll';
@NgModule({
imports: [
/* Other imports here */
Ng2PageScrollModule
]
})
export class AppModule {
}
在你的html组件中测试它
<a pageScroll href="#test">Testing</a>
<div id="test">
答案 2 :(得分:3)
对于Angular 6,您可以使用:
在您的路由模块中:
imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled'})]
然后在组件html中
<a (click)="onClick('AnchorId')">Click me!</a>
<a (click)="onClick('OtherAnchorId')">Click me, too!</a>
然后在组件ts
import { ViewportScroller } from '@angular/common';
@Component({
selector: 'component-selector',
templateUrl: './mycomponent.component.html'
})
export class MyComponent {
constructor(private viewportScroller: ViewportScroller) {}
public onClick(elementId: string): void {
this.viewportScroller.scrollToAnchor(elementId);
}
}
答案 3 :(得分:2)
最后,在Angular 7中为我工作:
HTML:
<h1 id='here'>Here</h1>
组件:
ngAfterViewInit() {
this.route.fragment.subscribe(fragment => {
this.fragment = fragment;
setTimeout(() => this.scrollToAnchor(), 10);
});
}
scrollToAnchor(): void {
try {
if (this.fragment) {
document.querySelector('#' + this.fragment).scrollIntoView();
}
} catch (e) { }
}
goToHere():void{
this.router.navigate(['/product'], { fragment: 'here' });
}
答案 4 :(得分:2)
因此,在最新的Angular上我花了一个小时的时间,其他解决方案可以进行初始导航,但无论如何,我都无法通过锚点滚动来处理导航历史。
换句话说,当我在浏览器中“后退”或“前进”时,URL会更新,但我无法使Angular滚动到正确的位置。从日志记录来看,Angular在回退/前进时实际上并没有确认该片段,因此没有触发滚动。
我受够了,决定订阅URL,并在找到片段时手动滚动,这是代码:
ngOnInit() {
this.router.events.subscribe(val => {
if (val instanceof NavigationEnd) {
let fragmentIdx = val.urlAfterRedirects.lastIndexOf('#');
if (fragmentIdx >= 0 && fragmentIdx < val.urlAfterRedirects.length - 1) {
let fragment = val.urlAfterRedirects.substring(fragmentIdx+1);
console.log('fragment: ' + fragment);
document.getElementById(fragment).scrollIntoView();
}
}
})
}
为清楚起见,您必须为要滚动到的目标元素指定id
。
此外,这就是我的链接:
<a routerLink="." fragment="anchor-name">Scroll To Anchor</a>
现在,我可以回访不同的锚点,并在回溯历史时看到滚动。希望它能对某人有所帮助!
答案 5 :(得分:2)
现代一线解决方案:
export class Component implements AfterViewInit {
constructor(
private viewportScroller: ViewportScroller
) { }
ngAfterViewInit(): void {
this.route.fragment.pipe(
first()
).subscribe(fragment => this.viewportScroller.scrollToAnchor(fragment));
}
}
答案 6 :(得分:0)
AfterViewCheck()
时都会调用 ChangeDetection
,所以这是一个不好的解决方案。
像使用AfterViewInit()
public ngAfterViewInit(): void {
this.subscription = this.route.fragment
.subscribe(fragment => {
const targetElement = this.document.querySelector('#' + fragment);
if (fragment && targetElement) {
targetElement.scrollIntoView();
} else {
window.scrollTo(0, 0);
}
});
}
public ngOnDestroy(): void {
this.subscription.unsubscribe();
}
答案 7 :(得分:0)
这是要添加到上面莎拉·杜波依斯(Sarah Dubois)答案中的更详细的示例。
导入路由器模块。
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
constructor(private route:ActivatedRoute,
private router:Router) {
router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
if (event.url) {
this.route.fragment.subscribe(fragment => this.fragment = fragment);
}
}
});
}
ngAfterViewChecked(): void {
try {
if(this.fragment != null) {
document.querySelector("a[name="+this.fragment+"]").scrollIntoView();
}
} catch (e) {
//console.log(e, 'error');
}
}
我喜欢使用querySelector,它将为您提供很多选项,您可以滚动到该元素。 https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
这适用于Angular 8:)