同じページのアンカー要素に簡単なスクロールをしようとしています。基本的に、ユーザーは「Try It」ボタンをクリックし、「login」というIDを持つページの下の領域にスクロールします。現在、基本的なid="login"
&<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>
私はそれがより簡単な解決策だと思う:
HTMLで:
<a [routerLink]="['/']" fragment="login"></a>
TypeScriptで:
ngOnInit() {
this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
}
ngAfterViewChecked(): void {
try {
if(this.fragment) {
document.querySelector('#' + this.fragment).scrollIntoView();
}
} catch (e) { }
}
Angular v6なので、anchorScrolling
に新しいRouterModule
オプションがあります。モジュールのインポートで設定できます:
imports: [
...,
RouterModule.forRoot(routes, {anchorScrolling: 'enabled'})
これにより、Angularは指定されたフラグメントのIDを持つ要素に自動的にスクロールします。
However️ただし、データが非同期にロードされる場合、これは機能しません。これを参照してください Githubの問題 。 ⚠️
スムーズスクロール はRouterModule
を介してまだ使用できませんが、手動で実行できます。
1)ターゲットを取得しますViewChild
を使用:
@ViewChild('pageInfo') pageInfo: ElementRef;
2)scrollIntoView
でnativeElement
を呼び出します。
const targetElement = this.pageInfo.nativeElement
targetElement.scrollIntoView({behavior: "smooth"})
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">
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();
}
これは、上記のサラデュボアの答えに追加するより詳細な例です。
ルーターモジュールをインポートします。
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 :)で動作します