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

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

下载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

购买SpreadJS正版授权,请点击“咨询在线客服”哟!

标签:JavaScript 表格控件Spread

来源:慧都

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年1月9日
下一篇 2019年1月9日

相关推荐

发表回复

登录后才能评论