请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

Joestar.Xu SpreadJS 开发认证
超级版主   /  发表于:2025-5-8 09:07  /   查看:38  /  回复:0
上一个章节我们介绍了 SpreadJS 的右键菜单和设计器的右键菜单之间的区别和关联,想必大家现在已经对右键菜单有了一个初步的认知,那么这一节我们将从多个实例角度来介绍如何自定义右键菜单。

在正式开始之前,还需要再介绍一下 SpreadJS 中不同区域右键菜单的区别。

在列头、行头上,右键菜单如下图所示:

image.png216985167.png

而在单元格区域,右键菜单如下图所示:

image.png791685485.png

可以看到,列头和行头的右键菜单和单元格区域的右键菜单是不同的,这是因为它们的右键菜单的触发条件不同。

因此,我们在自定义右键菜单时,需要根据不同的区域来进行不同的处理。

我们先从一个简单的 SpreadJS 的实例开始:

我们需要将右键菜单中的这两个选项移除掉,要如何实现呢?

image.png505271911.png

先把基础的重写框架搭好,如下:

  1. function ContextMenu() {}
  2. ContextMenu.prototype = new GC.Spread.Sheets.ContextMenu.ContextMenu(spread);
  3. ContextMenu.prototype.onOpenMenu = function (
  4.   menuData,
  5.   itemsDataForShown,
  6.   hitInfo,
  7.   spread
  8. ) {
  9.   console.log(itemsDataForShown);
  10. };
  11. spread.contextMenu = new ContextMenu();
复制代码


此时,我们在单元格区域按下右键,会看到控制台中的输出与右键菜单中的选项一一对应:

image.png417988280.png

然后我们可以采用两种不同的方式来实现这个需求:

1、直接修改 itemsDataForShown,删除对应的选项,但是这种方式的修改是临时性的。

这个操作需要我们在 onOpenMenu 函数中进行修改,如下:

  1. function ContextMenu() {}
  2. ContextMenu.prototype = new GC.Spread.Sheets.ContextMenu.ContextMenu(spread);
  3. ContextMenu.prototype.onOpenMenu = function (
  4.   menuData,
  5.   itemsDataForShown,
  6.   hitInfo,
  7.   spread
  8. ) {
  9.   for (let i = itemsDataForShown.length - 1; i >= 0; i--) {
  10.     if (
  11.       itemsDataForShown[i].name === "gc.spread.filter" ||
  12.       itemsDataForShown[i].name === "gc.spread.sort"
  13.     ) {
  14.       itemsDataForShown.splice(i, 1);
  15.     }
  16.   }
  17. };
  18. spread.contextMenu = new ContextMenu();
复制代码


需要注意的是,我们需要使用倒序遍历的方式来删除对应的选项,否则会出现数组越界的问题。

2、直接修改 menuData,删除对应的选项,但是这种方式的修改是永久性的。

这个操作不需要我们在 onOpenMenu 函数中进行修改,直接修改 spread.contextMenu.menuData 即可,如下:

  1. for (let i = spread.contextMenu.menuData.length - 1; i >= 0; i--) {
  2.   if (
  3.     spread.contextMenu.menuData[i].name === "gc.spread.filter" ||
  4.     spread.contextMenu.menuData[i].name === "gc.spread.sort"
  5.   ) {
  6.     spread.contextMenu.menuData.splice(i, 1);
  7.   }
  8. }
复制代码


同样的,我们也需要用到倒序遍历来删除对应的选项。

这两种方式的区别在于,第一种方式是临时性的,第二种方式是永久性的。也就是说,如果选择第一种方式,那么每次打开右键菜单的时候都会执行这个循环,删除对应的选项。而如果选择第二种方式,那么只会在初始化的时候执行一次这个循环,删除对应的选项。

因此,我们在实际开发中,应该根据具体的需求来选择不同的方式。

下面我们再来看一个实例:

我们需要将右键菜单中的这个选项有条件的禁用掉(当单元格中没有值的时候禁用,有值的时候启用),该如何实现呢?

image-4.png459772033.png

在遇到这种需要根据单元格的值来决定是否禁用的情况时,就需要用到 onOpenMenu 函数中的 itemsDataForShown 参数了,也就是说我们需要动态地去修改选项的属性,而不是直接修改 menuData,因为一旦修改了 menuData,那么将无法根据单元格的值来决定是否禁用。

因此,我们需要在 onOpenMenu 函数中进行修改,如下:

  1. function ContextMenu() {}
  2. ContextMenu.prototype = new GC.Spread.Sheets.ContextMenu.ContextMenu(spread);
  3. ContextMenu.prototype.onOpenMenu = function (
  4.   menuData,
  5.   itemsDataForShown,
  6.   hitInfo,
  7.   spread
  8. ) {
  9.   let cellValue = spread
  10.     .getActiveSheet()
  11.     .getValue(hitInfo.worksheetHitInfo.row, hitInfo.worksheetHitInfo.col);
  12.   itemsDataForShown.forEach((item) => {
  13.     if (item.name === "gc.spread.clearContents" && !cellValue) {
  14.       item.disable = true;
  15.     }
  16.   });
  17. };
  18. spread.contextMenu = new ContextMenu();
复制代码


来看一下具体的效果:

当单元格中存在值时,右键菜单中的这个选项是启用的:

image-5.png171455077.png

当单元格中不存在值时,右键菜单中的这个选项是禁用的:

image-5.png860237426.png

以上就是如何实现自定义右键菜单隐藏和禁用的方法,在一下个章节中我们将介绍如何新增右键菜单选项实现某些特定需求应该如何实现。

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部