在 SpreadJS 里新增右键菜单,把业务动作放到用户手边

表格应用里,很多操作不适合永远摆在工具栏上。它们只在某个单元格、某一行或某个状态下才有意义,比如"提交当前行""查看审批记录""插入业务明细""复制为系统格式"。Spread新增右键菜单 这个 demo 演示了一个很基础但很关键的扩展点:在 SpreadJS 默认右键菜单打开前,追加自己的菜单项,并把它绑定到自定义命令。

为什么这个细节重要

右键菜单的优势是上下文明确。用户在哪里点,系统就知道他大概率想处理哪里。对产品经理来说,这能减少页面按钮数量,让工具栏保持安静;对开发者来说,菜单项可以按选区、行列、锁定状态、数据类型动态出现,避免用户点到不该点的操作。

demo 中有两个动作:一是在菜单里追加"自定义右键菜单"和 yustest,二是当当前选区位于第二行时清空菜单项。后者看起来简单,却展示了权限和状态控制的雏形:同一个右键入口,不同位置可以有不同结果。

这类能力对后台系统很常见。表格行可能代表订单、合同、人员或设备,不同状态下可执行的动作不同。与其让用户先选中数据再去远处找按钮,不如把可用动作放在他正在查看的位置。

SpreadJS 的实现思路

实现分两步。第一步保存原来的 spread.contextMenu.onOpenMenu,再重写它;第二步用 spread.commandManager().register 注册菜单项对应的命令。这样菜单 UI 和业务动作不会混在一起。

JavaScript 复制代码
let oldF = spread.contextMenu.onOpenMenu;

spread.contextMenu.onOpenMenu = function (menuData, itemsDataForShown, hitInfo, spread) {
  itemsDataForShown.push({
    text: "自定义右键菜单",
    name: "customContextMenu",
    command: "customCommand"
  });

  let sel = spread.getActiveSheet().getSelections()[0];
  if (sel.row === 1) {
    itemsDataForShown.splice(0, itemsDataForShown.length);
  }
  oldF.apply(this, arguments);
};

itemsDataForShown 是即将展示的菜单项数组,向里面 push 就能追加入口;hitInfo 可用于判断右键发生的位置;getSelections()[0] 则拿到当前选择区域。demo 里用 splice 清空菜单,实际项目也可以只删除某些菜单项,或根据单元格值决定是否显示。

JavaScript 复制代码
spread.commandManager().register("customCommand", {
  canUndo: false,
  execute: function (spread, options) {
    console.log(arguments);
  }
});

可以扩展到哪些场景

这个模式可以用于行级审批、单元格批注、批量插入、查看修改记录、跳转详情页、复制特殊格式、触发后端流程。它也适合做"保护状态下仍允许部分操作"的精细控制:比如锁定单元格不能编辑,但仍允许查看说明或提交反馈。

需要注意,菜单只是入口,真正的数据修改最好放在命令里,并按需要支持撤销。demo 的 canUndo: false 很适合日志、弹窗、跳转这类动作;如果命令会改表格数据,建议结合 SpreadJS 的事务命令设计撤销和重做。

另外,菜单文本最好和业务语言一致,不要只写"操作一""处理"。右键菜单出现的时间很短,命名越具体,用户越不需要猜。 图标和分隔线也应服务于识别,而不是装饰。

给开发者的关键词

SpreadJS、ContextMenu、contextMenu.onOpenMenu、itemsDataForShown、hitInfo、getSelections、commandManager().register、canUndo、右键菜单扩展、JavaScript 电子表格控件。

小结

Spread新增右键菜单 展示的是把表格操作接到业务里的入口设计。它不需要重做整套菜单系统,只要在默认菜单打开前追加或过滤项,再让命令管理器承接动作,就能让 SpreadJS 的右键交互更贴近业务流程。

相关推荐
大明二代1 小时前
从 RAG 到有记忆的 Agent:Mastra Memory 与 PostgreSQL 实战
前端·javascript·人工智能
deli0071 小时前
代码截图一键出 PNG 实测:3 种窗口风格,长行超 95 字符会被裁
前端
大哥43091 小时前
慢 ≠ 挂:AI 搜索降级判定的设计,与一次 reasoning 模型排查复盘
前端
UaoN1 小时前
作为全栈开发者,为什么看到 Shopify 回归原生,我依然选择 React Native
前端·后端
PBitW2 小时前
行内编辑,前端如何兜底?😭😭😭
前端·面试
小羊没烦恼!2 小时前
C#综合揭秘——Entity Framework 并发处理详解
java·开发语言·前端·javascript·数据库·mysql·c#
wing982 小时前
人生第一个私活:不到 2 小时,到手 350 元
前端·后端·程序员
张张123y2 小时前
后端第十二课:Agent 开发(让大模型从“会答“升级到“会做“)
前端·大模型·llm·agent·rag
A小码哥3 小时前
大模型成本怎么降,5 个动作先做前两个
java·前端·spring