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

时间:2017-12-03 08:59:30

标签: angular

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

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

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

我怎样才能在角度2+中做同样的事情?

8 个答案:

答案 0 :(得分:16)

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

<p #myElem>Scroll to here!</p>

然后在包含属性ViewChild的组件中创建一个属性,并在其上调用.nativeElement.scrollIntoView

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

  ngOnInit() {
    this.MyProp.nativeElement.scrollIntoView({ behavior: "smooth", block: "start" });
  }
}

答案 1 :(得分:8)

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

firebase.auth().onAuthStateChanged

答案 2 :(得分:6)

您可以拦截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 );
                }
            }
         }
    });
}

答案 3 :(得分:1)

我们的混合动力车遇到了一些问题,这些都不起作用。如果您只想提供一个简单的解决方案,则还可以选择添加超时来退出Angular。

例如

<a (click)="onClick('foo')">

onClick(id: string): void {
    const el: HTMLElement|null = document.getElementById(id);
    if (el) {
      setTimeout(() =>
        el.scrollIntoView({behavior: 'smooth', block: 'start', inline: 'nearest'}), 0);
    }
  }

答案 4 :(得分:1)

我正在使用电容器包装Angular应用程序。 scrollIntoView无法正常工作,但是将其包装在 setTimeout()函数中,以使其能够进行同步调用。我不知道为什么尝试在构造函数中打开模态/对话框时,我遇到了类似的问题。 。

答案 5 :(得分:1)

它已经有一段时间被回答了,但是实现它的最干净的方法是对指令进行操作,该指令还提供了可重用性。

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

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)
    }
}

然后要做的就是在相关元素上添加该指令,以在单击该功能时触发该功能。

希望它可以帮助任何人。

答案 6 :(得分:0)

我只能通过将其包装在requestAnimationFramesetTimeout中来使其工作

@ViewChild('someElement') someElementRef: ElementRef;

...

requestAnimationFrame(() => {
  this.someElementRef.nativeElement.scrollIntoView({ behavior: 'smooth' });
});
<div #someElement>test</div>

答案 7 :(得分:0)

有 3 种使用 scrollIntoView

的简单方法

Link to Stackblitz

第一种方式

在 app.component.html 文件中:

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

<div>
  <h3 #point_1>Point 1</h3>
</div>

在 app.component.ts 文件中:

scrollPoint1(el: HTMLElement) {
  // el.scrollIntoView({behavior: "smooth"});
  el.scrollIntoView();
}

第二种方式

在 app.component.html 文件中:

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

<div>
  <h3 id="point_2">Point 2</h3>
</div>

在 app.component.ts 文件中:

scrollPoint2() {
  // document.getElementById("point_2").scrollIntoView({behavior: "smooth"});
  document.getElementById('point_2').scrollIntoView();
}

第三种方式

在 app.component.html 文件中:

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

<div>
  <h3 #point_3>Point 3</h3>
</div>

在 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();
}