如果表格完全显示在页面中,只有页面滚动条,我就可以工作了。使用
scrollIntoView
。我拥有的功能:
onBeamIdInputChange(id: string) {
const el = document.getElementById(id);
if (el) {
el.scrollIntoView({behavior: 'smooth', block: 'center'});
}
}
在模板中使用此内容:
<td mat-cell *matCellDef="let i = index"> <span [id]="i"></span>{{ i }} </td>
但我需要保持标题 div 和表头始终可见。所以我尝试了容器的固定高度,但是跳转到特定行不再起作用,它只会以我的容器为中心。
我的html或多或少是这样的:
<div>Content to keep always visible - <input matInput type="text" ...>Jump to id</input></div>
<div id="container" style="height: 500px; overflow: auto;">
<table mat-table> <!-- With sticky header -->
...
<td mat-cell *matCellDef="let i = index"> <span [id]="i"></span>{{ i }} </td>
...
</table>
</div>
如何跳转到具有这种嵌套滚动视图的单元格?
我尝试了https://stackoverflow.com/a/20958953/6165833将元素的父级的scrollTop设置为元素自己的offsetTop。但父级是
<ng-container matColumnDef="id">
而不是带有滚动区域的视图容器,所以它不起作用,而且对于角度组件来说似乎也有点脏。
编辑:在某些时候,我让它部分工作,自动滚动嵌套视图(容器),但前提是我之前滚动过主页。所以它会工作一次,然后就不再工作了,如果我在主页上再次滚动,它会再次工作一次等等。
就像如果我的页面已经以我的容器为中心,则对
scrollIntoView
的调用不起作用,但如果它必须以我的容器为中心,那么它也会在容器内滚动以显示搜索到的元素。
这种情况不再发生了,我不知道为什么不......
最后我在容器上使用了
scrollTo
,并且需要计算偏移量。
@ViewChild('container') container: ElementRef;
onBeamIdInputChange(id: string) {
const el = document.getElementById(id); // span element
if (el) {
const rowElement = el.parentElement.parentElement;
// We substract the sticky header for the offset
const offset = rowElement.offsetTop - rowElement.offsetHeight;
this.container.nativeElement.scrollTo({
top: offset,
left: 0,
behavior: 'smooth'
});
}
}
它似乎不是最干净或最强大的解决方案,但我没有找到任何其他方法让它工作。
根据建议,我得到了比之前的解决方案更干净的东西,使用 Angular 来检索元素,而不是依赖于
.parentElement
调用。
@ViewChild('tableDiv') tableDiv: ElementRef;
@ViewChildren('idElement') idElements: QueryList<ElementRef>;
onIdInputChange(id: string) {
const foundElement = this.idElements.toArray().find(item =>
item.nativeElement.id === id).nativeElement;
if (foundElement) {
// We ignore the header + two rows
const offset = foundElement.offsetTop - (foundElement.offsetHeight * 3);
this.tableDiv.nativeElement.scrollTo({ top: offset, left: 0, behavior: 'smooth' });
}
}
<div #tableDiv>
<table mat-table [dataSource]="myData">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> ID </th>
<td mat-cell *matCellDef="let dataRow" #idElement [id]="dataRow.id">
{ dataRow.id }}
</td>
</ng-container>
...