【问题标题】:How to add a horizontal scrollbar on top of the ag-grid如何在 ag-grid 顶部添加水平滚动条
【发布时间】:2019-04-02 06:34:55
【问题描述】:

我设置了一个 ag-grid,其中包含一系列用于单元格渲染的组件。当我的数据集加载时,垂直滚动效果很好,但水平滚动不明显,除非使用触控板或启用水平滚动的鼠标。

我希望能够在网格顶部添加滚动条以及在底部自动生成的滚动条吗?

有没有人遇到过这种情况,想办法解决吗?

提前致谢

【问题讨论】:

标签: ag-grid


【解决方案1】:

这个问题很老,但我在同样的问题上苦苦挣扎并想出了一些可行的方法。

? 想法

我的解决方案背后的主要思想是......

  • 当网格准备好时克隆 AgGrid 滚动条
  • 在网格顶部插入克隆的滚动条
  • 在两个滚动条上添加事件监听器以保持滚动位置同步
  • 使用MutationObserver 观察原始AgGrid 滚动条元素(和子元素)上的style 属性更改,以保持克隆滚动条的大小同步

⚡代码

以下代码适用于 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();
}

这很棘手,这一切都基于使克隆的滚动条与原始滚动条保持同步,但到目前为止它对我的用例非常有效。

祝你好运?

【讨论】:

  • 对于 Angular 用户,您可以将代码放在指令中并使用 AfterViewInit 生命周期钩子而不是 gridReady 事件,以便在每个网格上轻松重用该行为!
  • 谢谢,它大部分都有效,只是左边的固定列似乎有问题。
  • 我添加了代码来查找元素 ag-horizo​​ntal-left-spacer,然后克隆它并设置代码显示的样式,并且它可以与固定列正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 2019-03-30
  • 2022-01-26
  • 1970-01-01
  • 2018-05-19
相关资源
最近更新 更多