You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于中间主体滚动事件更新AG-Grid固定列样式

问题描述

我希望在固定列与中间显示列组“重叠”时更新其样式。左侧固定列只需在onBodyScroll事件中判断e.left > 0即可,操作简单。但右侧固定列的处理更棘手,无法通过AG Grid的api/columnApi明确获取右侧偏移量。我考虑过使用refs或调用ColumnModel的私有属性,但想知道是否有更优方案,比如使用AG Grid官方函数?

当前实现(依赖私有属性)

以下是一种实现方式,但用到了ColumnModel的私有属性:

//...
const [leftPinnedOverlaying, setLeftPinnedOverlaying] = useState(false);
const [rightPinnedOverlaying, setRightPinnedOverlaying] = useState(true);
const hasMounted = useRef(false);

return (
  <div style={{ width: '100%', height: '100%' }}>
    <pre>
    {JSON.stringify({leftPinnedOverlaying,rightPinnedOverlaying})}
    </pre>

    <div className="example-wrapper">        
      <div
        id="myGrid"
        style={{
          height: '100%',
          width: '100%',
        }}
        className="ag-theme-alpine"
      >
        <AgGridReact
          defaultColDef={{ resizable: true }}
          debug={true}
          rowData={rowData}
          onGridReady={onGridReady}
          onBodyScroll={(e)=> {
            // first pass seems to pass non-ideal state
            if(!hasMounted.current) {
              hasMounted.current=true
              return
            }
            setLeftPinnedOverlaying(e.left > 0);
            const columnModel = e.columnApi.columnModel;
            // Get around these properties being private by indexing via array
            const scrollWidth = columnModel["scrollWidth"] || 0;
            const bodyWidth = columnModel["bodyWidth"] || 0;

            setRightPinnedOverlaying((e.left+scrollWidth) < bodyWidth)

          }}
        >
          <AgGridColumn
            headerName="Athlete"
            field="athlete"
            width={150}
            pinned="left"
            cellStyle={leftPinnedOverlaying ? {backgroundColor: 'blue'}:{backgroundColor: 'white'}}
          />
// ...
  </div>
 </div>
</div>)
优化方案(基于官方API)

依赖私有属性存在风险——这类属性可能在AG Grid版本更新中被修改或移除。推荐使用以下官方API实现,稳定性更强:

实现思路

  1. 在onBodyScroll事件中获取当前水平滚动位置scrollLeft(即e.left)
  2. 用公开API计算左侧固定列总宽度、中间列总宽度
  3. 结合网格可视宽度,判断右侧固定列是否与中间列重叠

示例代码

onBodyScroll={(e) => {
  if(!hasMounted.current) {
    hasMounted.current = true;
    return;
  }
  const scrollLeft = e.left;
  const gridPanel = e.api.getGridPanelElement();
  const viewportWidth = gridPanel.clientWidth;

  // 计算左侧固定列总宽度
  const leftPinnedCols = e.columnApi.getPinnedColumns('left');
  const totalLeftWidth = leftPinnedCols.reduce((sum, col) => sum + col.getActualWidth(), 0);

  // 计算中间非固定列总宽度
  const centerCols = e.columnApi.getAllDisplayedColumns().filter(col => !col.isPinned());
  const totalCenterWidth = centerCols.reduce((sum, col) => sum + col.getActualWidth(), 0);

  // 判断右侧固定列是否处于重叠状态
  const isRightOverlaying = (scrollLeft + viewportWidth) < (totalLeftWidth + totalCenterWidth);
  setRightPinnedOverlaying(isRightOverlaying);

  // 左侧固定列判断逻辑保持不变
  setLeftPinnedOverlaying(scrollLeft > 0);
}}

内容的提问来源于stack exchange,提问作者Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 20:50:30