JsTree - 在上下文菜单中订购项目

JsTree - Order items in context menu

有什么方法可以对上下文菜单中的项目进行排序 (context.menu.items)? (还有一个子菜单项 (contextmenu.items.submenu) - 如果这与上下文菜单不同)。

菜单项未按我在代码中的顺序呈现。

我在文档中找不到任何相关信息: https://www.jstree.com/api/#/?q=contextmenu&f=$.jstree.defaults.contextmenu.items

我发现这在 jstree 中被忽略了。简短的回答是似乎没有很好和可靠的方法来实现这一点。 您的选择是:

  • 控制您声明上下文菜单项的顺序,并希望您的目标浏览器与您一致。
    是的,我读到您尝试过此操作,但请再次准确检查您在控制台中看到的内容,而不是 Chrome 开发工具上下文菜单中的内容。我发现我们在开发工具中看到的顺序与实际顺序不同。如果有疑问,请调试并暂停上下文菜单对象的最终状态,然后尝试使用 for...in 循环迭代其属性。这也是 jstree 幕后发生的事情(见下文)。
    如果您的配置从一个全新的对象开始,或者您重用并覆盖从 $.jstree.defaults.contextmenu.items() 获得的内容,这也很重要。要完全控制属性定义顺序,请确保从普通对象文字开始,然后按照您希望它出现的顺序从 $.jstree.defaults.contextmenu.items() 中复制您需要的内容。这是在顶部呈现自定义菜单项 "Open" 的建议:

          "contextmenu": {
              "items" : function(node) {
                  var _ctxmenu = $.jstree.defaults.contextmenu.items();
                  var ctxmenu = {
                    "open": {
                        "label": "Open"
                        "action" function(){....},
                        "separator_after"   : true,
                    },
                    "rename": _ctxmenu.rename,
                    "remove": _ctxmenu.remove,
                  };
                  return ctxmenu;
              }
          }
      
    如果我们直接使用从 $.jstree.defaults.contextmenu.items() 获得的上下文菜单并向其添加 "open" 对象,它将呈现在 "remove" 和 "rename" 下方的某个位置,因为它们已经被定义。

  • 到post-处理为上下文菜单生成的HTML。您需要订阅全局文档事件 "context_parse.vakata" :
    $(document).on("context_parse.vakata", function(evt, data){
        //process the data.element.children('li') array
    })
    在事件处理程序中,考虑分组和分隔符元素,您编写自己的重新排序逻辑。

正如我所说,这里没有简单的解决方案,例如简单的 ordering/weight 属性。

关于实施的一些细节解释了我们为什么在这里,以防您感兴趣。

整个上下文菜单生成魔术发生在 $.vakata.context._parse 方法中。它会将您构建的上下文菜单对象作为参数,并使用 $.each 迭代其属性,这就是 jstree 当前所依赖的顺序。现在这个 ($.each) internally uses the for..in loop. What MDN has to say about this loop is that it will iterate on enumerable properties in arbitrary order。因此,如果碰巧浏览器按照声明的顺序执行此操作,那是一个令人高兴的巧合,而不是规范强制要求的。这就是可靠性......但如果你能忍受这一点,它也可能更容易在这里实现。

在这种情况下,一个常见的解决方案是添加一些 ordering/weight 属性,并在构建上下文菜单时考虑它,但我没有看到这个在 3.3.4 版本中实现。第三种选择是修补您的 jstree 实例,如果这对您来说是可行的解决方案,则自己包含和维护它。