ag-grid - 如何在 ag-grid 顶部添加水平滚动条
问题描述
我设置了一个 ag-grid,其中包含一系列用于单元格渲染的组件。当我的数据集加载垂直滚动时效果很好,但水平滚动并不明显,除非使用触控板或启用水平滚动的鼠标。
我希望能够在网格顶部添加一个滚动条以及在底部自动生成一个滚动条吗?
有没有人遇到过这种情况,想出解决办法吗?
提前致谢
解决方案
这个问题很老,但我在同样的问题上苦苦挣扎并想出了一些可行的方法。
理念
我的解决方案背后的主要思想是......
- 网格准备好时克隆 AgGrid 滚动条
- 在网格顶部插入克隆的滚动条
- 在两个滚动条上添加事件侦听器以保持滚动位置同步
- 使用MutationObserver观察
style
原始 AgGrid 滚动条元素(和子元素)的属性变化,以保持克隆滚动条的大小同步
⚡ 代码
以下代码适用于 Angular,但概念与 Vanilla JS、React 或 Vue 相同。
首先,获取gridReady
事件挂钩:
<ag-grid-angular
...
(gridReady)="onGridReady()">
</ag-grid-angular>
在与事件关联的函数中,使用以下代码克隆 AgGrid 滚动条并保持滚动条同步:
// hold the `MutationObserver` to be disconnected when component is destroyed
private mutationObserver: MutationObserver;
onGridReady() {
// css class selectors
const headerSelector = '.ag-header';
const scrollSelector = '.ag-body-horizontal-scroll';
const scrollViewportSelector = '.ag-body-horizontal-scroll-viewport';
const scrollContainerSelector = '.ag-body-horizontal-scroll-container';
// get scrollbar elements
const scrollElement = document.querySelector(scrollSelector);
const scrollViewportElement = document.querySelector(scrollViewportSelector);
const scrollContainerElement = document.querySelector(scrollContainerSelector);
// create scrollbar clones
const cloneElement = scrollElement.cloneNode(true) as Element;
const cloneViewportElement = cloneElement.querySelector(scrollViewportSelector);
const cloneContainerElement = cloneElement.querySelector(scrollContainerSelector);
// insert scrollbar clone
const headerElement = document.querySelector(headerSelector);
headerElement.insertAdjacentElement('afterend', cloneElement);
// add event listeners to keep scroll position synchronized
scrollViewportElement.addEventListener('scroll', () => cloneViewportElement.scrollTo({ left: scrollViewportElement.scrollLeft }));
cloneViewportElement.addEventListener('scroll', () => scrollViewportElement.scrollTo({ left: cloneViewportElement.scrollLeft }));
// create a mutation observer to keep scroll size synchronized
this.mutationObserver = new MutationObserver(mutationList => {
for (const mutation of mutationList) {
switch (mutation.target) {
case scrollElement:
cloneElement.setAttribute('style', scrollElement.getAttribute('style'));
break;
case scrollViewportElement:
cloneViewportElement.setAttribute('style', scrollViewportElement.getAttribute('style'));
break;
case scrollContainerElement:
cloneContainerElement.setAttribute('style', scrollContainerElement.getAttribute('style'));
break;
}
}
});
// start observing the scroll elements for `style` attribute changes
this.mutationObserver.observe(scrollElement, { attributeFilter: ['style'], subtree: true });
}
销毁组件时,断开连接MutationObserver
以避免内存泄漏。
ngOnDestroy() {
// stop observing
this.mutationObserver.disconnect();
}
这很棘手,并且全部基于使克隆的滚动条与原始滚动条保持同步,但到目前为止它对我的用例非常有效。
祝你好运
推荐阅读
- android - 没有类名的 java.lang.ClassNotFoundException
- join - 用 awk 制表符分隔 2 个以上的表(n 个数字文件)文件
- jquery - 以原子方式选择下拉列表中的选定项目
- c# - 无法使用 streamWriter 和 json 发送具有此动词类型的内容主体
- performance - Taurus JSON 正文帖子
- jquery - 邮件表单提交,即使验证失败
- amazon-web-services - 使用 kinesis firehose 写入日志时出现垃圾
- javascript - javascript 上的正则表达式可以以感叹号开头吗?
- python - 如何在 spaCy 中获取句号?
- php - 将 PDO::ATTR_EMULATE_PREPARES 设置为 false 时,联合查询中的日期字段问题