如何让Kendo Grid在窗口大小变化时固定显示10行?
问题分析与解决方案:Kendo Grid固定显示10行适配窗口变化
我明白你想要实现的效果:不管窗口怎么调整,Kendo Grid始终刚好显示10行数据,而且当前的方案在添加上方元素后出现了布局异常。咱们一步步来拆解问题,然后给出修正后的代码。
先说说当前代码的问题
你的resizeGrid函数逻辑是用Grid的整体高度减去内部非内容区元素的高度来设置内容区高度,但这是基于Grid现有高度反向计算,而不是根据「要显示10行」这个目标来正向计算。当窗口变化或者上方添加元素后,Grid的可用空间被挤压,这个逻辑就无法保证内容区刚好放下10行。另外resizeWrapper直接把outerWrapper设为body高度,没有考虑Grid上方元素的占用空间,导致Grid被挤得变形。
核心思路
要固定显示10行,关键是先算出单行的高度,再用单行高度×10得到内容区需要的高度,然后再加上Grid其他部分(表头、分页栏等)的高度,得到Grid的整体高度,最后调整外层容器适配窗口。
修正后的代码实现
1. 完善resizeGrid函数(核心逻辑)
这个函数会先获取单行高度,计算出刚好放下10行的内容区高度,再调整Grid整体高度:
// 自定义获取滚动条宽度的工具函数(Kendo可能自带,这里做备用) $.fn.scrollbarWidth = function() { var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div></div>'); $('body').append(div); var w1 = $('div', div).innerWidth(); div.css('overflow-y', 'auto'); var w2 = $('div', div).innerWidth(); div.remove(); return w1 - w2; }; function resizeGrid() { // 获取Grid实例,确保Grid已初始化完成 var grid = $("#grid").data("kendoGrid"); if (!grid || !grid.tbody || grid.tbody.find("tr").length === 0) return; var gridElement = $("#grid"), dataArea = gridElement.find(".k-grid-content"), // 获取第一行的高度(假设所有行高度一致) rowHeight = grid.tbody.find("tr:first").outerHeight(), // 计算10行需要的高度,加上滚动条宽度(如果显示的话) desiredContentHeight = rowHeight * 10 + (dataArea.scrollbarWidth() || 0); // 计算Grid非内容区元素的总高度(表头、分页栏等,包含margin) var otherElementsHeight = 0; gridElement.children().not(".k-grid-content").each(function(){ otherElementsHeight += $(this).outerHeight(true); }); // 设置Grid整体高度,让内容区刚好放下10行 gridElement.height(desiredContentHeight + otherElementsHeight); }
2. 修正resizeWrapper函数(适配上方元素)
如果Grid上方有其他元素,需要把这些元素的高度从outerWrapper的高度中扣除:
function resizeWrapper() { // 替换成你Grid上方元素的选择器,比如#header、#topToolbar等 var topElementsHeight = $("#topElements").outerHeight(true) || 0; // outerWrapper高度 = 可用窗口高度 - 上方元素高度 $("#outerWrapper").height($('#body').innerHeight() - topElementsHeight); }
3. 初始化与调用调整
确保Grid完全初始化后再触发resize,避免获取不到行元素:
$(document).ready(function() { $("#grid").kendoGrid({ dataSource: { data: [ { userId: 11111, No: 1, isActive:true, date: new Date('12/12/2005 12:30 AM'), from: 'A', sm: 'testing', art: 'Shipped on', due: new Date('12/19/2005 11:30 PM')}, { userId: 22340, No: 2, isActive:true, date: new Date('12/12/2005 12:30 AM'), from: 'A', sm: 'test0', art: 'Shipped on', due: new Date('12/19/2005 11:30 PM')}, // 其他数据项... ], schema: { model: { fields: { userId: { editable: true }, date: { filterable: { ui: "datetimepicker"}}, isActive:false, No: { editable: true } } } }, pageSize: 10 }, sortable: true, reorderable: true, scrollable: true, resizable: true, filterable: true, columnMenu: true, pageable: { input: true, numeric: false }, columns: [ { field: 'No' ,width: 50 }, { field: 'userId', title: 'ID', template:"<span class=ul>#=userId#</span> </br> <span class='pie'>1/5</span>", width:60 } , { field: "isActive", headerTemplate: '!', template: '<span class="k-icon k-i-circle Unicode: e308" style="color: green; font-size: 28px;"></span> </br> <div class="div1"></div>', filterable:false , width: 40 }, // 其他列配置... ] }); // 延迟触发resize,确保Grid已渲染完成 setTimeout(function() { $(window).trigger("resize"); }, 100); $(window).resize(function() { resizeWrapper(); resizeGrid(); }); });
额外注意事项
- 如果你的行高是动态变化的(比如内容换行、单元格内容更新),需要在内容变化后重新调用
resizeGrid()。 - 要是Grid没有数据,代码里已经加了判断避免报错。
- 测试时可以调整窗口大小,看看Grid是否始终保持10行显示,上方元素添加后布局是否正常。
内容的提问来源于stack exchange,提问作者NewBie
相关产品推荐
相关产品推荐

