Tabulator表格编辑单元格高亮失效:滚动丢失/超50行无效果
问题:表格编辑单元格高亮失效问题
我想给表格中已编辑的单元格添加高亮效果,大部分情况正常,但行数到50行左右时,格式修改就不生效了。另外把窗口滚到表格底部放一会儿再往上滚,原本带高亮背景的行也会丢失格式。希望高亮能作用于所有行,且保持到表格重新加载为止。
现有实现代码
单元格高亮函数
var cellEditHighlight = function(cell){ var cellInitialValue = cell.getInitialValue(); var cellValue = cell.getValue(); if (!(cellInitialValue == null && cellValue == "") && (cellValue != cellInitialValue)) { cell.getElement().style.backgroundColor = "#FFFF00"; } }; table.on("cellEdited", cellEditHighlight);
批量更新提交函数
const inputValue = document.getElementById('itemNumberInput').value; const rows = table.getSelectedRows(); rows.forEach(function(row) { if (row.getData().status != "Complete") { if (inputValue) { row.update({"itemNumber":inputValue}); cellEditHighlight(row.getCell("itemNumber")); //row.update does not trigger cellEdited event } } });
解决方法
问题根源是表格大概率用了虚拟滚动/行复用机制:滚动时会回收看不见的行DOM,再重新渲染新行,直接修改DOM样式会随着DOM被复用而丢失。要持久化高亮,得把编辑状态存在数据中,再通过表格的样式逻辑动态应用。
修改数据结构,标记已编辑单元格
在单元格编辑或批量更新时,给对应行的数据添加标记,记录哪些单元格被修改过:// 更新高亮函数,同时标记数据 var cellEditHighlight = function(cell){ var cellInitialValue = cell.getInitialValue(); var cellValue = cell.getValue(); const isEdited = !(cellInitialValue == null && cellValue == "") && (cellValue != cellInitialValue); // 标记数据 const rowData = cell.getRow().getData(); if (!rowData.editedCells) rowData.editedCells = {}; rowData.editedCells[cell.getColumn().getId()] = isEdited; // 应用样式 if (isEdited) { cell.getElement().style.backgroundColor = "#FFFF00"; } else { cell.getElement().style.backgroundColor = ""; // 取消高亮 } };添加表格渲染回调,确保滚动时重新应用高亮
表格的cellRendered事件会在单元格渲染时触发,在这里根据数据标记重新设置样式:// 单元格渲染时检查标记,应用高亮 table.on("cellRendered", function(cell){ const rowData = cell.getRow().getData(); if (rowData.editedCells && rowData.editedCells[cell.getColumn().getId()]) { cell.getElement().style.backgroundColor = "#FFFF00"; } });调整批量更新逻辑,确保标记正确
批量更新时,调用修改后的cellEditHighlight即可自动完成数据标记和样式设置:const inputValue = document.getElementById('itemNumberInput').value; const rows = table.getSelectedRows(); rows.forEach(function(row) { if (row.getData().status != "Complete" && inputValue) { row.update({"itemNumber":inputValue}); const cell = row.getCell("itemNumber"); cellEditHighlight(cell); } });可选:用CSS类代替直接修改样式(更易维护)
先定义CSS类:.edited-cell { background-color: #FFFF00 !important; }再修改JS中的样式设置逻辑:
// 更新高亮函数 var cellEditHighlight = function(cell){ var cellInitialValue = cell.getInitialValue(); var cellValue = cell.getValue(); const isEdited = !(cellInitialValue == null && cellValue == "") && (cellValue != cellInitialValue); // 标记数据 const rowData = cell.getRow().getData(); if (!rowData.editedCells) rowData.editedCells = {}; rowData.editedCells[cell.getColumn().getId()] = isEdited; // 应用CSS类 if (isEdited) { cell.getElement().classList.add("edited-cell"); } else { cell.getElement().classList.remove("edited-cell"); } }; // 渲染回调也改成操作CSS类 table.on("cellRendered", function(cell){ const rowData = cell.getRow().getData(); if (rowData.editedCells && rowData.editedCells[cell.getColumn().getId()]) { cell.getElement().classList.add("edited-cell"); } else { cell.getElement().classList.remove("edited-cell"); } });
内容的提问来源于stack exchange,提问作者Tetris Maniac
相关产品推荐
相关产品推荐

