【问题标题】:jqGrid - click, right click, onSelectRowjqGrid - 单击,右键单击,onSelectRow
【发布时间】:2012-10-28 12:08:37
【问题描述】:

在 jqGrid 中,是否有一种“内置”方法可以在选择行之前知道单击了哪个鼠标按钮?

目前我们有一些动作绑定在 jqGrid 的“onSelectRow”事件上的 jqGrid。问题是当用户右键单击该行时,会引发 onSelectRow 事件并执行操作。我需要的是当用户右键单击一行时忽略“onSelectRow”。

编辑:我知道存在 onRightClickRow 事件,但它在 onSelectRow 和已执行的操作之后引发。

我发现我可以知道事件对象的“类型”单击了哪个按钮。单击时,右键单击时类型为“单击”,类型为“上下文菜单”....是否存在附加方式,或者我必须检查类型才能知道单击了什么按钮?

谢谢

【问题讨论】:

    标签: javascript jqgrid


    【解决方案1】:

    这是个好问题!这种行为的原因如下。 jqGrid 为整个网格<table> 元素上的事件contextmenu 注册一个事件处理程序,代码如下(参见here

    .bind('contextmenu', function(e) {
        td = e.target;
        ptr = $(td,ts.rows).closest("tr.jqgrow");
        if($(ptr).length === 0 ){return;}
        if(!ts.p.multiselect) { $(ts).jqGrid("setSelection",ptr[0].id,true,e);  }
        ri = ptr[0].rowIndex;
        ci = $.jgrid.getCellIndex(td);
        $(ts).triggerHandler("jqGridRightClickRow", [$(ptr).attr("id"),ri,ci,e]);
        if ($.isFunction(this.p.onRightClickRow)) {
            ts.p.onRightClickRow.call(ts,$(ptr).attr("id"),ri,ci, e);
        }
    });
    

    从代码中可以看出它调用setSelection方法并调用onRightClickRow回调并触发jqGridRightClickRow事件。因此,如果您不需要选择行并且不使用 onRightClickRowjqGridRightClickRow 您可以取消绑定事件处理程序

    $("#list").unbind("contextmenu");
    

    如果您确实想使用onRightClickRow 回调,或者如果您不确定是否需要在某处使用jqGridRightClickRow,您可以“子类化”事件处理程序。实现有点依赖于您使用的 jQuery 版本。从 jQuery 1.8 开始,应该使用另一个调用来获取在 DOM 元素上注册的当前事件。对应的代码大概如下:

    //$grid.unbind('contextmenu');
    
    var getEvents = $._data($grid[0], "events"); // $grid.data("events") in jQuery ver<1.8
    if (getEvents && getEvents.contextmenu && getEvents.contextmenu.length === 1) {
        var orgContextmenu = getEvents.contextmenu[0].handler;
        $grid.unbind('contextmenu', orgContextmenu);
        $grid.bind('contextmenu', function(e) {
            var oldmultiselect = this.p.multiselect, result;
            this.p.multiselect = true; // set multiselect to prevent selection
            result = orgContextmenu.call(this, e);
            this.p.multiselect = oldmultiselect; // restore multiselect
            return result;
        });
    }
    

    The demo 现场演示上述代码。

    【讨论】:

    • 非常好的解决方案 - 完美运行!!我不认为我自己能做到这一点!!谢谢 :) 只是额外的题外话简单问题...在“var oldmultiselect = this.p.multiselect, result;”行中。 “this.p.multiselect”和“result”之间的逗号是什么意思?我的 JS 知识还不错,但不记得应该如何工作?是否用于设置 result = undefined?
    • @AlexDn:它定义了两个变量oldmultiselectresult并初始化第一个。 JavaScript 没有块级变量。因此,在函数体中定义的所有变量都将在函数的开头定义。如果稍后将定义某个变量,则真正的代码将在第一行中定义,初始化为undefined,并在稍后进行分配而不是定义。所以建议在第一条语句var中定义函数内部需要的所有变量。我用var oldmultiselect = this.p.multiselect, result;
    • @AlexDn:如果有人遵循上述规则,则应在我的主代码开头定义getEventsorgContextmenu。在这种情况下,我没有遵守规则,只是为了能够在我的答案中发布完整的代码片段。在实际代码中,我将移动上面的getEventsorgContextmenu定义,并且我将在相应的语句中没有var,所以我将有赋值而不是初始化定义。
    • 谢谢你奥列格,你有非常描述性的答案!!
    【解决方案2】:

    这里列出了事件:http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events

    有一个 onRightClickRow 事件。

    另外,使用纯 jquery 事件对象和which 会告诉你。 http://api.jquery.com/event.which/

    您必须将第三个参数用于 onRowSelected 和 which 或您提到的类型。

    【讨论】:

    • 对,但在 onRightClickRow 引发之前,onSelectRow 引发并执行了操作,因此检查 onRightClickRow 中的“哪个”为时已晚:(
    • 我试过了,但是对于左键和右键单击,事件对象(onSelectRow 中的 3d 参数)在“which”属性中的值为 0 :(
    • 你不能在 if 语句中使用类型和上下文菜单吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多