ag-grid:滚动时将 header 保持在顶部
ag-grid: keep header on top while scrolling
我无法在滚动 ag-grid div 时将 table header 保持在 div 之上。是否有特定的 ag- class 可用于获取此信息?
谢谢
编辑:
有代码:
HTML:
<md-tab ng-repeat="tab in mbpTabs">
<md-tab-label>{{tab.title}}</md-tab-label>
<md-tab-body>
<div ag-grid="tab.mbpTable.table" class="ag-dark ag-scrolls"></div>
</md-tab-body>
</md-tab>
JS 网格定义如下:
this.cols = [{headerName: "Security",marryChildren: true,
children: [{headerName: "CTRL", field: this.FIELD_KEY_CTRL,hide: true,cellRenderer: MbpTable.prototype.ctrlRenderer.bind(this)},
{headerName: "Id", field: this.FIELD_KEY_ID,width: 0,hide: true},
{headerName: "Issuer", field: this.FIELD_KEY_ISSUER,width: 100},
{headerName: "Cusip", field: this.FIELD_KEY_CUSIP,width: 80,},
{headerName: "Board Label", field: this.FIELD_KEY_BOARD_LABEL,width: 150}]
},
{headerName: 'Best',marryChildren: true,
children: [{headerName: "Bid Size", field: this.FIELD_KEY_BEST_BID_SIZE, width: 125,cellClass:"mbp-ag-cell-best-bid",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)},
{headerName: "Bid Price", field: this.FIELD_KEY_BEST_BID_PRICE, width: 125,cellClass:"mbp-ag-cell-best-bid",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)},
{headerName: "Ask Price", field: this.FIELD_KEY_BEST_ASK_PRICE, width: 125,cellClass:"mbp-ag-cell-best-ask",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)},
{headerName: "Ask Size", field: this.FIELD_KEY_BEST_ASK_SIZE, width: 125,cellClass:"mbp-ag-cell-best-ask",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)}]
},
{headerName: this.headerMyOrder,marryChildren: true,
children: [{headerName: "Bid Size", field: this.FIELD_KEY_ORDER_BID_SIZE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.bidOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.sizeValueHandler.bind(this)},
{headerName: "Bid Price", field: this.FIELD_KEY_ORDER_BID_PRICE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.bidOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.priceValueHandler.bind(this)},//cellEditor: NumericCellEditor},
{headerName: "",headerCellTemplate:this.headerMyBidOrder, field: this.FIELD_KEY_ORDER_BID_ACTION,minWidth:18,maxWidth:18,width:18,cellClass:["mbp-ag-cell-order","mbp-ag-cell-order-action"],cellRenderer: MbpTable.prototype.bidOrderRenderer.bind(this)},
{headerName: "Ask Price", field: this.FIELD_KEY_ORDER_ASK_PRICE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.askOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.priceValueHandler.bind(this)},//cellEditor: NumericCellEditor},
{headerName: "Ask Size", field: this.FIELD_KEY_ORDER_ASK_SIZE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.askOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.sizeValueHandler.bind(this)},
{headerName: "",headerCellTemplate:this.headerMyAskOrder, field: this.FIELD_KEY_ORDER_ASK_ACTION,minWidth:18,maxWidth:18,width:18,cellClass:["mbp-ag-cell-order","mbp-ag-cell-order-action"],cellRenderer: MbpTable.prototype.askOrderRenderer.bind(this)}]}];
this.table={
columnDefs: this.cols,
rowData: MbpTable.prototype.createRndRows(numRows,offset,this),
rowSelection: 'multiple',
enableColResize: true,
enableSorting: true,
enableFilter: true,
groupHeaders: true,
...
};
出于业务原因,我在 table 定义中省略了以下选项。
ag- header classes in CSS 没有被修改。
已解决:我需要将高度属性添加到 div。
谢谢大家
我希望 table 中的 header 始终可见,即使您像这样在 window 中向下滚动。不确定这是否是 OP 想要的,但这是我的解决方案。
首先需要得到header元素和table
的body元素
header = document.querySelector('[ref="headerRoot"]');
body = document.querySelector('[ref="eBodyViewport"]');
// More on this later
original.position = header.style.position;
original.top = header.style.top;
original.zIndex = header.style.zIndex;
将滚动处理程序添加到 window
object,每次用户滚动时都会执行下面的逻辑
window.addEventListener("scroll", () => {
// More on this below
})
逻辑很简单。它使 header 粘性与否取决于它的位置
const shouldStick = header.getBoundingClientRect().top <= 0;
const shouldUnstick = body.getBoundingClientRect().top -
header.getBoundingClientRect().height > 0;
if (shouldStick) { stick(header); }
if (shouldUnstick) { unstick(header); }
最后添加一些css样式使其固定在window
的顶部
function stick(header) {
header.style.position = "fixed";
header.style.top = "0";
// this is optional, but if you have other contents that overlap the
// header you may want to adjust the zIndex accordingly
header.style.zIndex = "2";
}
function unstick(header) {
header.style.position = original.position;
header.style.top = original.top;
header.style.zIndex = original.zIndex;
}
这是 React 中的示例实现。您需要做的就是复制这个钩子并将其粘贴到组件的渲染方法中。就是这样。
import { useCallback, useRef, useEffect } from "react";
const useStickyHeader = () => {
const headerElementRef = useRef();
const bodyElementRef = useRef();
const stickyRef = useRef(false);
const originalStyles = useRef({ position: "", top: "", zIndex: "" });
useEffect(() => {
headerElementRef.current = document.querySelector('[ref="headerRoot"]');
bodyElementRef.current = document.querySelector('[ref="eBodyViewport"]');
const header = headerElementRef.current;
originalStyles.current.position = header.style.position;
originalStyles.current.top = header.style.top;
originalStyles.current.zIndex = header.style.zIndex;
}, []);
const onScroll = useCallback(() => {
const header = headerElementRef.current;
const body = bodyElementRef.current;
if (!header || !body) return;
let shouldStick = false;
let shouldUnstick = false;
if (!stickyRef.current) {
shouldStick = header.getBoundingClientRect().top <= 0;
if (shouldStick) stickyRef.current = true;
} else {
shouldUnstick =
body.getBoundingClientRect().top -
header.getBoundingClientRect().height >
0;
if (shouldUnstick) stickyRef.current = false;
}
if (shouldStick) {
header.style.position = "fixed";
header.style.top = "0";
// this is optional, but if you have other contents that overlap the
// header you may want to adjust zIndex accordingly
header.style.zIndex = "2";
}
if (shouldUnstick) {
const original = originalStyles.current;
header.style.position = original.position;
header.style.top = original.top;
header.style.zIndex = original.zIndex;
}
}, []);
useEffect(() => {
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
});
return stickyRef;
};
用法
function GridExample() {
useStickyHeader();
return (
<div style={{ width: "100%", height: "100%" }}>
<div className="grid-wrapper">
<div
style={{
height: "100%",
width: "100%"
}}
className="ag-theme-balham"
>
<AgGridReact
...
/>
</div>
</div>
</div>
);
}
实例
HTML:
gridAutoHeight = true in ag-grid-angular html 标签
TS:
window.addEventListener('scroll', this.scroll);
在 ngOnit()
scroll = (event: any): void => {
let headerElementRef;
let bodyElementRef;
headerElementRef = document.querySelector('[ref="headerRoot"]');
bodyElementRef = document.querySelector('[ref="eBodyViewport"]');
const nav = headerElementRef;
const body = bodyElementRef;
const offset = nav.getBoundingClientRect();
if (!nav) return;
if (window.pageYOffset > offset.top && !(body.getBoundingClientRect().top - nav.getBoundingClientRect().height > 0)) {
nav.style.position = 'fixed';
nav.style.top = 0;
nav.style.zIndex = "2";
nav.style.width = this.totalGridWidth + 'px';
} else {
nav.style.position = 'relative';
nav.style.top = '';
nav.style.zIndex = "";
nav.style.width = this.totalGridWidth + 'px';
}
}
简单的技巧是为行容器添加 css。
.ag-body-viewport {
overflow: scroll;
height: 300px;
}
相应地更新高度或宽度。
我无法在滚动 ag-grid div 时将 table header 保持在 div 之上。是否有特定的 ag- class 可用于获取此信息?
谢谢
编辑:
有代码:
HTML:
<md-tab ng-repeat="tab in mbpTabs">
<md-tab-label>{{tab.title}}</md-tab-label>
<md-tab-body>
<div ag-grid="tab.mbpTable.table" class="ag-dark ag-scrolls"></div>
</md-tab-body>
</md-tab>
JS 网格定义如下:
this.cols = [{headerName: "Security",marryChildren: true,
children: [{headerName: "CTRL", field: this.FIELD_KEY_CTRL,hide: true,cellRenderer: MbpTable.prototype.ctrlRenderer.bind(this)},
{headerName: "Id", field: this.FIELD_KEY_ID,width: 0,hide: true},
{headerName: "Issuer", field: this.FIELD_KEY_ISSUER,width: 100},
{headerName: "Cusip", field: this.FIELD_KEY_CUSIP,width: 80,},
{headerName: "Board Label", field: this.FIELD_KEY_BOARD_LABEL,width: 150}]
},
{headerName: 'Best',marryChildren: true,
children: [{headerName: "Bid Size", field: this.FIELD_KEY_BEST_BID_SIZE, width: 125,cellClass:"mbp-ag-cell-best-bid",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)},
{headerName: "Bid Price", field: this.FIELD_KEY_BEST_BID_PRICE, width: 125,cellClass:"mbp-ag-cell-best-bid",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)},
{headerName: "Ask Price", field: this.FIELD_KEY_BEST_ASK_PRICE, width: 125,cellClass:"mbp-ag-cell-best-ask",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)},
{headerName: "Ask Size", field: this.FIELD_KEY_BEST_ASK_SIZE, width: 125,cellClass:"mbp-ag-cell-best-ask",cellRenderer: MbpTable.prototype.szPriceRenderer.bind(this)}]
},
{headerName: this.headerMyOrder,marryChildren: true,
children: [{headerName: "Bid Size", field: this.FIELD_KEY_ORDER_BID_SIZE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.bidOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.sizeValueHandler.bind(this)},
{headerName: "Bid Price", field: this.FIELD_KEY_ORDER_BID_PRICE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.bidOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.priceValueHandler.bind(this)},//cellEditor: NumericCellEditor},
{headerName: "",headerCellTemplate:this.headerMyBidOrder, field: this.FIELD_KEY_ORDER_BID_ACTION,minWidth:18,maxWidth:18,width:18,cellClass:["mbp-ag-cell-order","mbp-ag-cell-order-action"],cellRenderer: MbpTable.prototype.bidOrderRenderer.bind(this)},
{headerName: "Ask Price", field: this.FIELD_KEY_ORDER_ASK_PRICE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.askOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.priceValueHandler.bind(this)},//cellEditor: NumericCellEditor},
{headerName: "Ask Size", field: this.FIELD_KEY_ORDER_ASK_SIZE, width: 80,cellClass:"mbp-ag-cell-order",editable: true,cellRenderer: MbpTable.prototype.askOrderRenderer.bind(this),cellEditor: "text",newValueHandler: MbpTable.prototype.sizeValueHandler.bind(this)},
{headerName: "",headerCellTemplate:this.headerMyAskOrder, field: this.FIELD_KEY_ORDER_ASK_ACTION,minWidth:18,maxWidth:18,width:18,cellClass:["mbp-ag-cell-order","mbp-ag-cell-order-action"],cellRenderer: MbpTable.prototype.askOrderRenderer.bind(this)}]}];
this.table={
columnDefs: this.cols,
rowData: MbpTable.prototype.createRndRows(numRows,offset,this),
rowSelection: 'multiple',
enableColResize: true,
enableSorting: true,
enableFilter: true,
groupHeaders: true,
...
};
出于业务原因,我在 table 定义中省略了以下选项。
ag- header classes in CSS 没有被修改。
已解决:我需要将高度属性添加到 div。
谢谢大家
我希望 table 中的 header 始终可见,即使您像这样在 window 中向下滚动。不确定这是否是 OP 想要的,但这是我的解决方案。
首先需要得到header元素和table
的body元素header = document.querySelector('[ref="headerRoot"]');
body = document.querySelector('[ref="eBodyViewport"]');
// More on this later
original.position = header.style.position;
original.top = header.style.top;
original.zIndex = header.style.zIndex;
将滚动处理程序添加到 window
object,每次用户滚动时都会执行下面的逻辑
window.addEventListener("scroll", () => {
// More on this below
})
逻辑很简单。它使 header 粘性与否取决于它的位置
const shouldStick = header.getBoundingClientRect().top <= 0;
const shouldUnstick = body.getBoundingClientRect().top -
header.getBoundingClientRect().height > 0;
if (shouldStick) { stick(header); }
if (shouldUnstick) { unstick(header); }
最后添加一些css样式使其固定在window
的顶部function stick(header) {
header.style.position = "fixed";
header.style.top = "0";
// this is optional, but if you have other contents that overlap the
// header you may want to adjust the zIndex accordingly
header.style.zIndex = "2";
}
function unstick(header) {
header.style.position = original.position;
header.style.top = original.top;
header.style.zIndex = original.zIndex;
}
这是 React 中的示例实现。您需要做的就是复制这个钩子并将其粘贴到组件的渲染方法中。就是这样。
import { useCallback, useRef, useEffect } from "react";
const useStickyHeader = () => {
const headerElementRef = useRef();
const bodyElementRef = useRef();
const stickyRef = useRef(false);
const originalStyles = useRef({ position: "", top: "", zIndex: "" });
useEffect(() => {
headerElementRef.current = document.querySelector('[ref="headerRoot"]');
bodyElementRef.current = document.querySelector('[ref="eBodyViewport"]');
const header = headerElementRef.current;
originalStyles.current.position = header.style.position;
originalStyles.current.top = header.style.top;
originalStyles.current.zIndex = header.style.zIndex;
}, []);
const onScroll = useCallback(() => {
const header = headerElementRef.current;
const body = bodyElementRef.current;
if (!header || !body) return;
let shouldStick = false;
let shouldUnstick = false;
if (!stickyRef.current) {
shouldStick = header.getBoundingClientRect().top <= 0;
if (shouldStick) stickyRef.current = true;
} else {
shouldUnstick =
body.getBoundingClientRect().top -
header.getBoundingClientRect().height >
0;
if (shouldUnstick) stickyRef.current = false;
}
if (shouldStick) {
header.style.position = "fixed";
header.style.top = "0";
// this is optional, but if you have other contents that overlap the
// header you may want to adjust zIndex accordingly
header.style.zIndex = "2";
}
if (shouldUnstick) {
const original = originalStyles.current;
header.style.position = original.position;
header.style.top = original.top;
header.style.zIndex = original.zIndex;
}
}, []);
useEffect(() => {
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
});
return stickyRef;
};
用法
function GridExample() {
useStickyHeader();
return (
<div style={{ width: "100%", height: "100%" }}>
<div className="grid-wrapper">
<div
style={{
height: "100%",
width: "100%"
}}
className="ag-theme-balham"
>
<AgGridReact
...
/>
</div>
</div>
</div>
);
}
实例
HTML: gridAutoHeight = true in ag-grid-angular html 标签
TS:
window.addEventListener('scroll', this.scroll);
在 ngOnit()
scroll = (event: any): void => {
let headerElementRef;
let bodyElementRef;
headerElementRef = document.querySelector('[ref="headerRoot"]');
bodyElementRef = document.querySelector('[ref="eBodyViewport"]');
const nav = headerElementRef;
const body = bodyElementRef;
const offset = nav.getBoundingClientRect();
if (!nav) return;
if (window.pageYOffset > offset.top && !(body.getBoundingClientRect().top - nav.getBoundingClientRect().height > 0)) {
nav.style.position = 'fixed';
nav.style.top = 0;
nav.style.zIndex = "2";
nav.style.width = this.totalGridWidth + 'px';
} else {
nav.style.position = 'relative';
nav.style.top = '';
nav.style.zIndex = "";
nav.style.width = this.totalGridWidth + 'px';
}
}
简单的技巧是为行容器添加 css。
.ag-body-viewport {
overflow: scroll;
height: 300px;
}
相应地更新高度或宽度。