如何在角度为2+的元素上调用scrollIntoView

End*_*ono 9 angular

我想在组件中的HTML元素上调用scrollIntoView.

在angular.js 1中我可以在控制器中做这样的事情:

var element = $window.document.getElementById(id);
element.scrollIntoView({ behavior: "smooth", block: "start" });
Run Code Online (Sandbox Code Playgroud)

如何在角度2+中做同样的事情?

End*_*ono 25

首先在元素中添加模板引用变量(#myElem):

<p #myElem>Scroll to here!</p>
Run Code Online (Sandbox Code Playgroud)

然后在具有属性的组件中创建一个属性ViewChild,并调用.nativeElement.scrollIntoView它:

export class MyComponent {
  @ViewChild("myElem") MyProp: ElementRef;

  ngOnInit() {
    this.MyProp.nativeElement.scrollIntoView({ behavior: "smooth", block: "start" });
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 每次出现时,都是"不要使用nativeElement",也不讨论"推荐方式". (25认同)
  • 有关nativeElement的建议(或反推荐)具体是什么? (8认同)

Uli*_*lko 10

您可以在Angular 2+中实现与元素相同的动画滚动,只需在点击时传递元素,如下所示:

<button mat-fab (click)="scroll(target)">
    <i class="material-icons">
      arrow_drop_down
    </i>
 </button>
<div #target></div>

public scroll(element: any) {
    element.scrollIntoView({ behavior: 'smooth' });
  }
Run Code Online (Sandbox Code Playgroud)


Alb*_*lio 7

您可以拦截NavigationEnd事件

    private scrollToSectionHook() {
    this.router.events.subscribe(event => {
        if (event instanceof NavigationEnd) {
            const tree = this.router.parseUrl(this.router.url);
            if (tree.fragment) {
                const element = document.querySelector('#' + tree.fragment);
                if (element) {
                    setTimeout(() => {
                        element.scrollIntoView({behavior: 'smooth', block: 'start', inline: 'nearest'});
                    }, 500 );
                }
            }
         }
    });
}
Run Code Online (Sandbox Code Playgroud)


Vươ*_*iện 6

有3种简单的方法来使用scrollIntoView

链接到 Stackblitz

第一种方式

在 app.component.html 文件中:

<button (click)="scrollPoint1(point_1)">
  Click to scroll - Point 1
</button>

<div>
  <h3 #point_1>Point 1</h3>
</div>
Run Code Online (Sandbox Code Playgroud)

在 app.component.ts 文件中:

scrollPoint1(el: HTMLElement) {
  // el.scrollIntoView({behavior: "smooth"});
  el.scrollIntoView();
}
Run Code Online (Sandbox Code Playgroud)

第二种方式

在 app.component.html 文件中:

<button click)="scrollPoint2()">
  Click to scroll - Point 2
</button>

<div>
  <h3 id="point_2">Point 2</h3>
</div>
Run Code Online (Sandbox Code Playgroud)

在 app.component.ts 文件中:

scrollPoint2() {
  // document.getElementById("point_2").scrollIntoView({behavior: "smooth"});
  document.getElementById('point_2').scrollIntoView();
}
Run Code Online (Sandbox Code Playgroud)

第三条路

在 app.component.html 文件中:

<button (click)="scrollPoint3()">
  Click to scroll - Point 3
</button>

<div>
  <h3 #point_3>Point 3</h3>
</div>
Run Code Online (Sandbox Code Playgroud)

在 app.component.ts 文件中:

@ViewChild('point_3') private my_point_3: ElementRef;
scrollPoint3() {
  // this.my_point_3.nativeElement.scrollIntoView({behavior: "smooth"});
  this.my_point_3.nativeElement.scrollIntoView();
}
Run Code Online (Sandbox Code Playgroud)


gil*_*gil 5

不久前已经得到了回答,但实现它的最干净的方法是按照指令执行此操作,这也提供了可重用性。

这是指令的示例,它将通过鼠标单击触发将元素滚动到视图中:

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
    selector: '[ScrollIntoViewOnClick]'
})
export class ScrollIntoViewOnClickDirective {

    constructor(private _elementRef: ElementRef) {
    }

    @HostListener('click', ['$event.target'])
    scrollIntoView() {
        setTimeout(() => {
            this._elementRef.nativeElement.scrollIntoView({behavior: 'smooth'});
        }, 200)
    }
}
Run Code Online (Sandbox Code Playgroud)

那么您所要做的就是在相关元素上添加该指令,以便在单击该元素时触发该功能。

希望它对任何人都有帮助。