angular 滚动到对应的html节点

前面了解了如何通过render来操作dom,那我们遇到需要跳转到页面特定节点的需求该如何办?还是通过使用@ViewChild的方法来实现。

控制展示页面里面某个可滚动区域

这种情况比较常见,有一个页面里面的子区域,这个区域是固定高度,可以上下滑动查看,这时候有需求,当展示这个子区域的时候,希望是先滑动到底部。

首先看看html结构:

1
2
3
4
5
<div class="all-sell scrollBeautiful" #scrollMe [ngStyle]="allHeightActive">
<ul class="all-container-list" [ngStyle]="sellListHeightActive" *ngIf="!depthLoading">
<!-- ....其他可滑动内容 -->
</ul>
</div>

可以看到,我们声明了一个模板变量#scrollMe用来给ts来控制。再看看ts:

1
@ViewChild('scrollMe') sellContent: ElementRef;

我们将html中的模板引用变量声明为一个子视图。然后我们可以控制它的滚动高度:

1
this.sellContent.nativeElement.scrollTop = this.sellContent.nativeElement.scrollHeight;

获得原生元素的滚动总高度,然后设置元素的当前滚动高度为总高度,即可实现需求。

但是,在实际操作的过程中,尝试了很久都没起作用。查来查去才发现,元素上面有个*ngIf,当ngIf的表达式为true的时候立马去设置高度并不能获取到实际高度。所以这里需要加一个延迟:

1
2
3
timer(0).subscribe(() => {
this.sellContent.nativeElement.scrollTop = this.sellContent.nativeElement.scrollHeight;
});

还是要特别注意这一点:ngIf的情况下,设置Dom属性的时候需要加个延迟,否则获取不到实际的值。

控制跳转到某个子视图节点

有时候我们跳转到一个页面,同事需要跳转到这个页面的特定子节点,但是我们的routernavigator方法并没有支持跳转到标签。我们还是需要通过@ViewChild的方式来进行跳转。
继续来看html:

1
2
3
4
<!-- 谷歌验证 -->
<div class="person-center-list" #googleCode id="googleCode">
<!-- ...其他html -->
</div>

我们创建了模板引用变量#googleCode,方便在ts中控制Dom。再看ts:

1
@ViewChild('googleCode') googleCode: ElementRef;

使用@ViewChild声明了元素的render,然后我们使用scrollIntoView方法来跳转到对应Dom:

1
this.googleCode.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' });

看看scrollIntoView这个方法(MDN scrollIntoView()):
Element.scrollIntoView() 这个方法可以让当前元素滚动到浏览器窗口的可视区域内。
该方法的参数有三种:

  • 无参数,等同于element.scrollIntoView(true)
  • alignToTop: boolean,即element.scrollIntoView(alignToTop),两种情况:
    • true: 元素的顶端将和其所在滚动区的可视区域的顶端对齐。
    • false: 元素的底端将和其所在滚动区域的可视区域的底端对齐。
  • Object型参数:
    • behavior: 定义缓动动画,值为auto|instant|smooth。默认为auto
    • block: 定义元素区域,值为start|center|end|nearest,默认为center
    • inline: 值为start|center|end|nearest,默认为nearest

其中,

  • scrollIntoView() === scrollIntoView(true) === scrollIntoView({block: 'start', inline: 'nearest'}).
  • scrollIntoView(false) === scrollIntoView({block: 'end', inline: 'nearest'})

两种滚动的需求,两种滚动的方式。