文档章节

深入解析如何自定义SpreadJS右键菜单(三)

x
 xiaochuachua
发布于 02/12 09:56
字数 1448
阅读 0
收藏 0

下载SpreadJS最新试用版

注意:本文适用Spread JS版本是V11及以上版本。

获取本文的Demo请点击此处

了解MenuView

MenuView类的全名是GC.Spread.Sheets.ContextMenu.MenuView,它是SpreadJS界面元素的渲染,Spread JS将此类作为用户自定义的接口放出,以便于Spread JS用户可以方便地进行扩展和定制。

MenuView包括了一个Constructor构造器以及两个方法,分别是createMenuItemElement和getCommandOptions。getCommandOptions是用来获取对应右键菜单项绑定的命令的参数。本例是采用Dom绑定事件来实现菜单功能,因此暂不涉及此方法,如果用绑定命令的方式指定右键菜单的功能时,可以方便地在此方法中执行自定义逻辑,或者修改命令参数。

本例中关注的关键点在于MenuView的createMenuItemElement方法,当用户在页面上右键点击触发右键菜单事件时,Spread JS会调用此方法来执行右键菜单Dom的渲染操作。因此,我们可以通过该方法来加入我们自定义的内容。

准备右键菜单项,实现color picker的逻辑

OK,现在大家已经了解了关于MenuView的作用,结合《深入解析如何自定义Spread JS右键菜单(上)》的内容,现在开始准备右键菜单项的定义,并且实现一个简单的color picker。

首先,定义color picker菜单项,并添加到右键菜单中。代码如下:

var colorPickers = {
    text: "颜色选择器",
    name: "gc.spread.colorPicker",
    workArea: "viewport",
    subMenu:
        [{
            text: "背景色:",
            name: "selectColorPicker1"
        },{
            text: "字体色:",
            name: "selectColorPicker2"
        }]
};
var menuData = spread.contextMenu.menuData;
menuData.splice(1, 0, colorPickers);

以上代码不详细解释,只是说明一点,本例是采用Dom注册事件的方式来实现的功能,因此定义右键菜单项时并没有command属性,这不影响右键菜单的呈现。

其次,定义右键菜单执行的命令,命令分为两个,一个控制背景色,一个控制字体色。用命令实现功能的原因是命令可以方便用户执行撤回操作。代码如下:

/*
*  定义本例中用到的两个命令,
*  使用命令有个优点,就是方便用户执行撤回操作
* */
spread.commandManager().register("colorPicker_backColor",
    {
        canUndo: true,
        execute: function (context, options, isUndo) {
            var Commands = GC.Spread.Sheets.Commands;
            // 在此加cmd
            options.cmd = "colorPicker_backColor";
            if (isUndo) {
                Commands.undoTransaction(context, options);
                return true;
            } else {
                Commands.startTransaction(context, options);
                changeColor(spread, options.color, true);
                Commands.endTransaction(context, options);
                return true;
            }
        }
    });
spread.commandManager().register("colorPicker_foreColor",
    {
        canUndo: true,
        execute: function (context, options, isUndo) {
            var Commands = GC.Spread.Sheets.Commands;
            // 在此加cmd
            options.cmd = "colorPicker_foreColor";
            if (isUndo) {
                Commands.undoTransaction(context, options);
                return true;
            } else {
                Commands.startTransaction(context, options);
                changeColor(spread, options.color, false);
                Commands.endTransaction(context, options);
                return true;
            }
        }
    });
function changeColor(spread, color, flag){
    var sheet = spread.getActiveSheet();
    var selections = sheet.getSelections();
    if(selections && selections.length > 0){
        // 重要:挂起sheet绘制
        sheet.suspendPaint();
        selections.forEach(function (item) {
            var cellRange = sheet.getRange(item.row, item.col, item.rowCount, item.colCount);
            // 当flag为true时改变背景色,否则改变字体色
            if(flag){
                cellRange.backColor(color);
            }else {
                cellRange.foreColor(color);
            }
        });
        // 重要:恢复绘制
        sheet.resumePaint();
    }
}

最后,我们来实现一个基于Dom的Color Picker:

/*
*  创建颜色选择面板,并注册事件
* */
function createColorpicker(flag) {
    var colors = ['rgb(255,255,255)',
        'rgb(0,255,255)', 'rgb(255,0,255)',
        'rgb(255,255,0)', 'rgb(255,0,0)',
        'rgb(0,255,0)', 'rgb(0,0,255)',
        'rgb(0,0,0)', 'rgb(64,64,64)',
        'rgb(128,128,128)'];
    var colorPicker = $("<div id='colorPicker'></div>");
    for(var i=0; i<colors.length; i++){
        var color = $("<span class='colorPicker colorPickerBorderMouseout' mycolor='"+colors[i]+"' style='background-color:"+colors[i]+"'></span>");
        color.mouseenter(function () {
            $(this).removeClass("colorPickerBorderMouseout");
            $(this).addClass("colorPickerBorderMouseenter");
        });
        color.mouseout(function () {
            $(this).removeClass("colorPickerBorderMouseenter");
            $(this).addClass("colorPickerBorderMouseout");
        });
        color.click(function () {
            var that = $(this);
            var color = that.attr("mycolor");
            var spread = GC.Spread.Sheets.findControl(document.getElementById("ss"));
            var sheet = spread.getActiveSheet();
            var commandName = "colorPicker_foreColor";
            if(flag){
                commandName = "colorPicker_backColor";
            }
            spread.commandManager().execute({
                cmd: commandName,
                sheetName: sheet.name(),
                color : color
            });
        });
        colorPicker.append(color);
    }
    return colorPicker;
}

将Color Picker加入右键菜单项

现在我们通过代码,将我们实现的color picker加入到右键菜单中。首先,定义自己的MenuView类,代码如下:

// 通过重写MenuView类,将自定义功能加入右键样式
function CustomMenuView() { }

第二步,继承原MenuView的功能。我们并不想自己实现整个右键菜单,因此我们需要用到原右键菜单的大部分样式与功能。代码如下:

// 继承原MenuView的功能
CustomMenuView.prototype = new GC.Spread.Sheets.ContextMenu.MenuView();

第三步,重写原生createMenuItemElement方法。重点来了,就是在这里加入自己的代码逻辑。代码如下:

CustomMenuView.prototype.createMenuItemElement = function (menuItemData) {
CustomMenuView.prototype.createMenuItemElement = function (menuItemData) {
    // 先执行原类的方法,继承右键菜单的样式
    var menuItemView = GC.Spread.Sheets.ContextMenu.MenuView.prototype.createMenuItemElement.call(this, menuItemData);
    /*
    * 添加自己的样式。
    *
    *   menuItemView 是右键菜单当前项的容器div,
    *   自定义的样式可以在此添加。
    *
    *   需要注意的是,如果想引入第三方控件,比如datepicker之类,
    *   可能会与SpreadJS的样式与事件产生冲突,
    *   因此除非您从技术上做过充分的验证,
    *   否则不推荐在此设计引入过重的第三方控件。
    * */
    if (menuItemData.name === "selectColorPicker1") {
        $(menuItemView).append(createColorpicker(1));
        return menuItemView;
    } else if (menuItemData.name === "selectColorPicker2") {
        $(menuItemView).append(createColorpicker());
        return menuItemView;
    }else {
        return menuItemView;
    }
};

在SpreadJS渲染右键菜单时,每生成一项,都会调用createMenuItemElement方法。在重写createMenuItemElement时,关键点有以下几处:

1、 执行原createMenuItemElement的逻辑,获取menuItemView实例;

GC.Spread.Sheets.ContextMenu.MenuView.prototype.createMenuItemElement.call(this, menuItemData);

我们通过执行这句代码让SpreadJS为我们生成一个右键菜单,并且返回了menuItemView的实例,这个实例就是当前右键菜单项所在的Dom。

2、 对menuItemView实例进行操作;

if (menuItemData.name === "selectColorPicker1") {
        $(menuItemView).append(createColorpicker(true));
        return menuItemView;
    } else if (menuItemData.name === "selectColorPicker2") {
        $(menuItemView).append(createColorpicker(false));
        return menuItemView;
    }else {
        return menuItemView;
        }

从设计上来讲,右键菜单中还是不宜引入过重的第三方控件的,如果一些动手能力强且脑洞比较大的同学想这样做,前期的技术调研一定要充分,只有很好地兼容Spread JS右键菜单的组件,才能让我们愉快地进行开发工作。

SpreadJS

 

本文转载自:https://www.grapecity.com.cn/blogs/how-to-customize-spread-right-click-menu-part2

x
粉丝 0
博文 225
码字总数 49214
作品 0
私信 提问
SpreadJS 表格控件发布 V11 版本,新增图表及前端 PDF 导出

日前,全球最大的控件提供商葡萄城宣布,SpreadJS 纯前端表格控件正式发布V11 版本。新版本亮点颇多,不但为用户带来期待已久的图表功能,还新增前端导出 PDF、列分组等功能,在数据可视化方...

葡萄城技术团队
2017/12/08
811
2
SpreadJS在线表格编辑器发布V11版本,新增对图表和纯前端PDF导出支持

SpreadJS 在线表格编辑器是类似在线 Excel 功能和外观的表格编辑程序,也是 SpreadJS 桌面设计器的在线版本,提供源代码,您可自由定制,任意扩展。该产品内嵌了 SpreadJS,离线和在线方式均...

葡萄城技术团队
2017/12/14
2
0
SpreadJS与Vue集成,苏宁集团『极客办公』系统开发案例

“造极”如今已成为苏宁集团的年度核心关键词。“造极”在具体工作上的体现,代表着苏宁不断追求极致的工匠精神,即对待每一个环节,都要严格要求、精益求精。“极客办公”系统,正是在这种环...

葡萄城技术团队
08/30
55
0
从零开始,SpreadJS新人学习笔记【第5周】

复制粘贴、单元格格式和单元格类型 本周,让我们一起来学习SpreadJS 的复制粘贴、单元格格式和单元格类型,希望我的学习笔记能够帮助你们,从零开始学习 SpreadJS,并逐步精通。 在此前的学习...

葡萄城技术团队
07/23
11
0
SpreadJS v12.1更新亮点之设计器的新特性

下载SpreadJS v12.1 SpreadJS 表格控件——V12.1 新特性 SpreadJS 是一款基于 HTML5 的纯 JavaScript 电子表格和网格功能控件,以“高速低耗、纯前端、零依赖”为产品特色,被开发人员誉为“...

xiaochuachua
05/16
12
0

没有更多内容

加载失败,请刷新页面

加载更多

全面兼容IE6/IE7/IE8/FF的CSS HACK写法

浏览器市场的混乱,给设计师造成很大的麻烦,设计的页面兼容完这个浏览器还得兼容那个浏览器,本来ie6跟ff之间的兼容是很容易解决的。加上个ie7会麻烦点,ie8的出现就更头疼了,原来hack ie...

前端老手
20分钟前
5
0
常用快递电子面单批量打印api接口对接demo-JAVA示例

目前有三种方式对接电子面单: 1.快递公司:各家快递公司逐一对接接口 2.菜鸟:支持常用15家快递电子面单打印 3.快递鸟:仅对接一次,支持常用30多家主流快递电子面单打印 目前也是支持批量打...

程序的小猿
24分钟前
6
0
Yii 框架中rule规则必须搭配验证函数才能使用

public $store_id;public $user_id;public $page;public $limit;public $list;public $mch_list;public $cart_id;public $is_community;public $shop_id;public $cart_typ......

chenhongjiang
26分钟前
4
0
Flutter使用Rammus实现阿里云推送

前言: 最近新的Flutter项目有“阿里云推送通知”的需求,就是Flutter的App启动后检测到有新的通知,点击通知栏然后跳转到指定的页面。在这里我使用的是第三方插件Rammus来实现通知的推送,之...

EmilyWu
26分钟前
42
0
Knative 实战:三步走!基于 Knative Serverless 技术实现一个短网址服务

短网址顾名思义就是使用比较短的网址代替很长的网址。维基百科上面的解释是这样的: 短网址又称网址缩短、缩短网址、URL 缩短等,指的是一种互联网上的技术与服务,此服务可以提供一个非常短...

阿里巴巴云原生
41分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部