在jsgrid表头实现全选复选框,尝试将相关代码封装到IIFE中
嘿,我看你是把jsgrid全选复选框的逻辑封装到IIFE里后碰到问题了对吧?之前功能正常,封装后出状况大概率是作用域隔离或者事件绑定失效的坑,我给你整理了一套完整的解决方案,帮你把逻辑完美封装起来还不影响功能:
解决jsgrid全选复选框IIFE封装后的问题
下面是一个经过优化的封装代码,同时我会标注关键的注意点,帮你避开常见的坑:
var jsgridCheckBox = (function($) { // 内部私有变量:存储选中的行数据 var selectedItems = []; // 选中单个行的逻辑 var selectItem = function(item) { // 避免重复添加相同行(通过item的唯一id判断) if (!selectedItems.some(i => i.id === item.id)) { selectedItems.push(item); // 可选:给选中的行添加高亮样式 $(`.jsgrid-row[data-item-id="${item.id}"]`).addClass("selected-row"); } }; // 取消选中单个行的逻辑 var unselectItem = function(item) { selectedItems = selectedItems.filter(i => i.id !== item.id); // 移除行的高亮样式 $(`.jsgrid-row[data-item-id="${item.id}"]`).removeClass("selected-row"); }; // 全选/取消全选核心逻辑 var selectAllCheckBox = function(isChecked, gridSelector) { const $grid = $(gridSelector); // 获取表格所有数据项 const allItems = $grid.jsGrid("getItems"); const $dataRows = $grid.find(".jsgrid-data-row"); if (isChecked) { // 全选:批量添加所有行到选中列表,更新UI allItems.forEach(item => selectItem(item)); $dataRows.addClass("selected-row"); $dataRows.find(".row-checkbox").prop("checked", true); } else { // 取消全选:清空选中列表,重置UI selectedItems = []; $dataRows.removeClass("selected-row"); $dataRows.find(".row-checkbox").prop("checked", false); } }; // 初始化表头复选框及事件绑定 var initHeaderCheckbox = function(gridSelector) { const $grid = $(gridSelector); const $firstHeaderCell = $grid.find(".jsgrid-header-cell").first(); // 给表头添加全选复选框(避免重复添加) if (!$firstHeaderCell.find(".select-all-checkbox").length) { $firstHeaderCell.prepend('<input type="checkbox" class="select-all-checkbox" style="margin-right:8px;" />'); } // 绑定全选复选框的change事件 $firstHeaderCell.find(".select-all-checkbox").on("change", function() { selectAllCheckBox($(this).is(":checked"), gridSelector); }); // 绑定行内复选框的change事件(用事件委托兼容动态加载的行) $grid.on("change", ".row-checkbox", function() { const $row = $(this).closest(".jsgrid-data-row"); const item = $row.data("item"); // 假设行元素上存储了对应的数据项 $(this).is(":checked") ? selectItem(item) : unselectItem(item); // 同步表头复选框状态:所有行都选中时才勾选表头 const totalRows = $grid.find(".row-checkbox").length; const checkedRows = $grid.find(".row-checkbox:checked").length; $firstHeaderCell.find(".select-all-checkbox").prop("checked", totalRows === checkedRows); }); }; // 暴露给外部的接口:让外部能初始化、获取选中项、清空选择 return { init: initHeaderCheckbox, getSelectedItems: function() { // 返回数组副本,避免外部直接修改内部私有变量 return [...selectedItems]; }, clearSelection: function() { selectedItems = []; $(".jsgrid-data-row").removeClass("selected-row"); $(".select-all-checkbox").prop("checked", false); } }; })(jQuery); // 把jQuery传入IIFE,避免依赖全局$,提升代码健壮性
关键注意点&踩坑指南:
- 作用域隔离:把jQuery作为参数传入IIFE,避免依赖全局的
$,同时确保内部函数能正常使用jQuery。 - 事件委托:行内复选框用事件委托绑定(
$grid.on("change", ".row-checkbox", ...)),这样jsgrid动态加载的新行也能触发选择事件。 - 状态同步:行内复选框点击后,要同步表头复选框的状态,避免出现“部分行选中但表头仍勾选”的不一致情况。
- 私有变量保护:通过返回数组副本的方式暴露选中项,避免外部代码直接修改内部的
selectedItems数组。
使用方式:
在你的jsgrid初始化完成后,调用这个封装好的初始化方法即可:
// 假设你的jsgrid选择器是#myJsGrid $("#myJsGrid").jsGrid({ // 你的jsgrid配置项(比如columns、data等) columns: [ // 记得给行添加复选框列 { headerTemplate: "<input type='checkbox' class='row-checkbox' />", itemTemplate: "<input type='checkbox' class='row-checkbox' />" }, // 其他列配置... ], // 表格加载完成后初始化全选功能 onLoaded: function() { jsgridCheckBox.init("#myJsGrid"); } });
如果还是有问题,可以先检查:表头复选框是否正确添加到DOM、事件是否绑定成功(用浏览器控制台的Elements/Events面板排查)、行元素是否正确存储了对应的数据项。
内容的提问来源于stack exchange,提问作者amdg
相关产品推荐
相关产品推荐

