【问题标题】:Dynamically change jquery contextmenu动态改变jquery contextmenu
【发布时间】:2020-01-02 21:34:25
【问题描述】:

我正在使用这个jquery plugin。菜单的实例化如下所示:

$.contextMenu({
    selector:'.disposition-menu',
    zIndex: 120,

    callback: function(key, options) {
        var stepID = $(this).closest('.card').attr("id").substring(5);
        handle_disposition(key,stepID);

    },
    items: {
        "pin": {name: "Pin to top"},
        "unpin": {name:"Unpin"},
        "complete": {name: "Mark step completed"},
        "remove": {name: "Remove step from Map"},
   },
   events: {
       show: function(){}, //this is where I'm lost
       hide: function(){} //this is where I'm lost
   },
    trigger: 'hover'
}); 

'handle disposition' 函数与 php 和数据库交互,将 '.card' 在数据库中记录为固定或取消固定,以便在重新加载页面时正确显示。 HTML 是这样的 bootstrap 4 卡片:

<div class="card" >
    <div class="card-header ">
        <table class="title-table">
            <tr>
                <td>...</td>
                <td>...</td>
                <td>...</td>
                <td class="disposition-menu">&vellip;</td>
            </tr>
        </table>
    </div>

    <div class="card-body">
        ...{body content}
    </div>
</div>

我想做的是在 pin 和 unpin 菜单项之间切换。一次只能在菜单上显示其中一个。如果该项目已经“固定”(即在数据库中标记,并由 '.card' html 中的数据属性表示),则应该出现“取消固定”......反之亦然。同样,一旦在菜单上单击“Pin...”,应立即更改菜单以隐藏“Pin”项并显示“Unpin”项,反之亦然

我查看了该插件的文档,但在使用带有冒号(例如选择器:)和回调的键之后的函数时,我有点新手。该插件显然有一个"visible:" 键,还有“显示:”和“隐藏:”键(按照this issue 使用,但我不知道如何将这些元素串在一起以实现我的目标。

【问题讨论】:

    标签: javascript jquery dom contextmenu


    【解决方案1】:

    使用build:

    https://swisnl.github.io/jQuery-contextMenu/docs.html#build

    如果在注册时发现构建回调,则菜单未构建 马上。菜单创建延迟到菜单的位置 实际上是调用来显示的。

    $.contextMenu({
      selector: ".menu",
      build: function($trigger) {
        var options = {
          callback: function(key, options) {
            var m = "clicked: " + key;
            alert(m);
          },
          items: {}
        };
    
        if ($trigger.hasClass('pin')) {
          options.items.unpin = {name: "unpin"};
        } else {
          options.items.pin = {name: "pin"};
        }
    
        return options;
      }
    });
    .menu{
        width: 100px;
        padding: 10px;
        background: red;
        margin: 10px;
        color: #FFF;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.0/jquery.contextMenu.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.0/jquery.contextMenu.min.js"></script>
    
    <div class="menu pin">Pin</div>
    <div class="menu">Unpin</div>

    按需示例:

    https://swisnl.github.io/jQuery-contextMenu/demo/dynamic-create.html

    编辑:

    $.contextMenu({
      selector: ".disposition-menu",
      build: function($trigger) {
        var options = {
          callback: function(key, options) {
            if(key == "pin")
                $trigger.removeClass("unpin").addClass("pin");
            else if(key == "unpin")
                $trigger.removeClass("pin").addClass("unpin");
          },
          items: {}
        };
    
        if ($trigger.hasClass('pin')) {
          options.items.unpin = {name: "unpin"};
        } else {
          options.items.pin = {name: "pin"};
        }
    
        return options;
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.0/jquery.contextMenu.css" rel="stylesheet"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.0/jquery.contextMenu.min.js"></script>
    <div class="card" >
        <div class="card-header ">
            <table class="title-table">
                <tr>
                    <td>...</td>
                    <td>...</td>
                    <td>...</td>
                    <td class="disposition-menu">&vellip;</td>
                </tr>
            </table>
        </div>
    
        <div class="card-body">
            ...{body content}
        </div>
    </div>

    【讨论】:

    • 太棒了。这为我指明了正确的方向。然而,在 HTML 中,只有一个元素 &lt;td class="disposition-menu"&gt;&amp;vellip;&lt;/td&gt;。因此,pin 和 unpin 必须切换到同一个元素,而不是两个单独的元素。你能澄清一下你的代码在这种情况下是如何工作的吗?为了清楚起见,我已将 HTML 添加到我的问题中。代码 sn-p 也没有做任何事情。
    • 另外,如果我正确阅读了文档,$trigger 是显示菜单的事件。就我而言,我不希望每次显示菜单时都会更改菜单,只有在单击 pinunpinmenu 项时才会更改。
    • 添加类到 disposition-menu 并在右键单击时根据这些类动态构建上下文是这里的关键,请在上面找到编辑后的答案。
    • 我的上下文中没有右键单击。不知道你指的是什么。
    【解决方案2】:

    这是我解决“菜单项交换”问题的方法。感谢@ahed-kabalan 为我指明了正确的方向。

    HTML 并没有改变我上面发布的问题。再次为方便起见:

    <div class="card" >
        <div class="card-header ">
            <table class="title-table">
                <tr>
                    <td>...</td>
                    <td>...</td>
                    <td>...</td>
                    <td class="disposition-menu">&vellip;</td>
                </tr>
            </table>
        </div>
    
        <div class="card-body">
            ...{body content}
        </div>
    </div>
    

    修改了 JS 以在单击特定菜单项并使用可见键时触发回调。此解决方案包括单击时修改的菜单项和不受影响的菜单项。悬停时出现菜单,回调仅在菜单项选择时触发。 unpin 项目默认设置为visible: false - 即最初只有pin 选项会出现在菜单中。由于build 真正专注于构建一个全新的菜单,因此在我的情况下没有必要。 JS 现在看起来像这样:

    $.contextMenu({
        selector:'.disposition-menu',
        zIndex: 120,
        callback: function(key, options) {
            
            var stepID = $(this).closest('.card').attr("id").substring(5);
            alert(stepID);
            handle_disposition(key,stepID);
            
        },
        items: {
            "pin": {name: "Pin to top",
                callback: function(key, opt) {
                    opt.items['pin'].visible = false;
                    opt.items['unpin'].visible = true;
                }
            },
            "unpin": {name:"Unpin",
                callback: function(key, opt) {
                    opt.items['pin'].visible = true;
                    opt.items['unpin'].visible = false;
                }
            },
            "complete": {name: "Mark step completed"},
            "remove": {name: "Remove step from Map"}
       },
       trigger: 'hover'
    });
    

    希望其他人会觉得这很有用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      • 2016-02-03
      • 1970-01-01
      相关资源
      最近更新 更多