如何在Kendo UI for jQuery TreeView中实现复选框单选功能
Kendo UI for jQuery TreeView 复选框单选高性能实现方案
原有方案卡顿的核心原因是每次勾选都全量遍历所有节点,且对每个非选中节点调用
node.set("checked", false),每次set操作都会触发TreeView的UI重绘,500+节点会触发数百次重绘,自然出现卡顿。
核心优化思路
单选场景下同一时间最多只有1个处于勾选状态的节点,完全不需要全量遍历所有节点,只需缓存上一次选中的节点,每次新勾选时仅更新上一次选中节点的状态即可,单次操作仅触发1次UI重绘,性能可提升数百倍。同时可以利用TreeView原生checkChildren配置自动处理父子节点级联状态,无需手动遍历子节点。
实现代码
优化后的核心逻辑(推荐方案,无全量遍历)
// 初始化TreeView并获取实例 const treeView = $("#treeview-kendo").kendoTreeView({ template: kendo.template($("#treeview").html()), dataSource: [{ id: 1, text: "My Documents", expanded: true, spriteCssClass: "rootfolder", items: [ { id: 2, text: "Kendo UI Project", expanded: true, spriteCssClass: "folder", items: [ { id: 3, text: "about.html", spriteCssClass: "html" }, { id: 4, text: "index.html", spriteCssClass: "html" }, { id: 5, text: "logo.png", spriteCssClass: "image" } ] }, { id: 6, text: "Reports", expanded: true, spriteCssClass: "folder", items: [ { id: 7, text: "February.pdf", spriteCssClass: "pdf" }, { id: 8, text: "March.pdf", spriteCssClass: "pdf" }, { id: 9, text: "April.pdf", spriteCssClass: "pdf" } ] } ] }], checkboxes: { checkChildren: true // 保留原有级联配置即可 }, check: onCheck, loadOnDemand: true }).data("kendoTreeView"); // 在TreeView实例上挂载缓存变量,避免全局污染 treeView._lastCheckedItem = null; // 重写勾选事件 function onCheck(e) { const currentItem = this.dataItem(e.node); // 若为取消勾选操作,直接清空缓存即可 if (!currentItem.checked) { this._lastCheckedItem = null; return; } // 仅更新上一次勾选的节点,无需遍历全量节点 if (this._lastCheckedItem && this._lastCheckedItem !== currentItem) { // Kendo会根据checkChildren配置自动同步该节点下所有子节点的勾选状态,无需手动遍历 this._lastCheckedItem.set("checked", false); } // 更新缓存为当前勾选节点 this._lastCheckedItem = currentItem; }
备用批量操作方案(适用于必须全量遍历的特殊场景)
如果业务逻辑确实需要全量遍历节点,可以通过暂停DataSource事件触发,操作完成后一次性通知UI更新,避免多次重绘:
function onCheck(e) { const currentItem = this.dataItem(e.node); const dataSource = this.dataSource; // 暂停DataSource的事件通知,所有set操作不会触发UI更新 dataSource.pauseEvents(); // 原有遍历逻辑,这里不会触发多次重绘 traverse(dataSource.data(), function(node) { if (node != currentItem) { node.set("checked", false); } }); // 恢复事件通知,一次性触发UI更新 dataSource.resumeEvents(); // 手动触发TreeView重绘同步所有状态 this.refresh(); }
两种方案都可以将500+节点的操作耗时从1-2秒降低到10ms以内,完全不会出现卡顿冻结的情况。
内容的提问来源于stack exchange,提问作者user3565914
相关产品推荐
相关产品推荐

