我有一个动态列表,该列表会异步地获取其数据,并希望在加载列表时将特定元素滚动到视图中。
列表的构建类似于以下:
<div class="items" *ngFor="let item of functionThatGetsItems(); let i = index" [id]="'MyList' + i">
<div class="title">
{{ item.title }}
</div>
<div class="content">
{{ item.content }}
</div>
</div>
您可以看到,这些项目具有一个简单的基本字符串及其数字的ID。假设我想触发滚动到MyList31
。加载并渲染列表后,如何使用此类ID获取元素并滚动到它?
我已经四处搜索,发现了您应该做的方式,而不是这样做,以及如何使用ViewRefs做到这一点,但是这些似乎对动态元素不起作用,还是它们有?我该怎么做?
您希望ID在ng-for创建的实际项目上,而不是ng-for本身。从组件传递数据到列表时,这将消除对任何额外逻辑的需求。
// inside ngAfterViewInit() to make sure the list items render or inside ngAfterViewChecked() if you are anticipating live data using @Inputs
const itemToScrollTo = document.getElementById('item-' + id);
// null check to ensure that the element actually exists
if (itemToScrollTo) {
itemToScrollTo.scrollIntoView(true);
}
<div class="list" *ngFor="let item of functionThatGetsItems(); let i = index">
<div class="list-item" id="item-{{i}}">
<div class="title">
{{ item.title }}
</div>
<div class="content">
{{ item.content }}
</div>
</div>
</div>
这不是严格的角度,但是您可以做document.querySelector('#MyList31').scrollIntoView()
。
参考https://developer.mozilla.org/en-us/docs/web/api/element/scrollintoview
对于严格的角度,本文可能会帮助您http://www.benlesh.com/2013/02/angular-jular-js-scrolling-to-element-element-element-element-element-element-by-id.html
我设法使用属性绑定来解决此问题。
首先,当我收到定义要滚动的项目的参数时,我将其保存为组件属性。
this.toScrollInto = Object.keys(params)[0];
然后,在构建它的NGFOR内部,我将其绑定到它中,并使用短路来调用功能,如果有匹配。
<div class="items" *ngFor="let item of functionThatGetsItems(); let i = index"
#itemRef
[class.scrolled]="i == this.toScrollInto && scrollIntoView(itemRef)">
<div class="title">
{{ item.title }}
</div>
<div class="content">
{{ item.content }}
</div>
</div>
函数scrollIntoView(Element)
然后使用提供的角参考来处理滚动。
使用模板参考并调用本机scrollIntoView()
方法。在您的html中:
<h2 #scrollToMe>Hi there</h2>
在您的组件中:
@ViewChild('scrollToMe') scrollToMe: ElementRef;
...
this.scrollToMe.nativeElement.scrollIntoView({ behavior: 'smooth' })
behavior: 'smooth'
动画过渡。