有没有用于显示嵌套上下文菜单的淘汰插件?

时间:2015-04-01 09:50:24

标签: jquery-ui knockout.js

是否有用于显示嵌套上下文菜单的淘汰插件?

我的具体需求是显示列表项的上下文菜单,其中包含" SendTo" menuitem和可能的子项必须在运行时设置。

1 个答案:

答案 0 :(得分:0)

在明显缺乏合适的插件时,我采用了更直接的Knockout方法。我确信代码可以更加优雅地包装在自定义绑定中,但这是我提出的解决方案,如果有人需要类似的东西。在我的情况下,菜单是每次打开时构建的,因为它在我的用例中是有意义的。我确信代码可以轻松地针对其他场景进行自定义。

所以...标记:
  <li data-bind="event: { contextmenu: $root.showSendToMenu }/> 用于显示右键单击项目的弹出菜单。 以及菜单本身的标记:

@*The send to popup menu*@
<ul class="context-menu" data-bind="visible:contextMenu.activeElement, style:{left:contextMenu.left, top:contextMenu.top}, template: { name: 'menu-item-template', foreach: contextMenu.items }, event: { mouseleave: contextMenu.contextMouseLeave }"></ul>

@*Template for a menu item*@
<script type="text/html" id="menu-item-template">
    <li>
        <!-- ko if: children -->
        <span data-bind="text:text"></span>
        <ul data-bind="template: { name: 'menu-item-template', foreach: children }"></ul>
        <!-- /ko -->
        <!-- ko if: !children -->
        <a href="#" data-bind="text:text, click:$root.onContextClick"></a>
        <!-- /ko -->
    </li>
</script>

在viewModel中,我有以下代码(TypeScript):

contextMenu = { activeElement: ko.observable(null), left: ko.observable('0px'), top: ko.observable('200px'), items: ko.observableArray(<MenuItem[]>[]), contextMouseLeave : () => { this.contextMenu.activeElement(null); } };

    showSendToMenu = (item, event) => {

        //Set menu position
        this.contextMenu.left(event.pageX + 'px');
        this.contextMenu.top(event.pageY + 'px');

        //Build the menu
        var lines = [];
        for (var i = 0; i < this.prodLines().length; i++) {
            var line = this.prodLines()[i];

            if (line.lists().length > 0) {
                var lists = [];
                for (var j = 0; j < line.lists().length; j++) {
                    var list = line.lists()[j];
                    lists.push(new MenuItem(list.name(), null, list));
                }
                lines.push(new MenuItem(line.name + "->", lists, line));
            }
        }

        var items = [new MenuItem("SendTo ->", lines)];

        //Set the menu
        this.contextMenu.items(items);
        this.contextMenu.activeElement(item);
    }


    onContextClick = (menuItem: MenuItem) => {
        var sendToList = menuItem.tag;
        var item = this.contextMenu.activeElement();
        this.dropToList(item, sendToList);
        //Hide the menu
        this.contextMenu.activeElement(null);
    }

最后,我使用这段css使菜单表现得像菜单一样:

.context-menu {
  position: absolute;
  padding: 0;
  margin: 0;
  z-index: 1030;
  background-color: #dddddd;
  box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
  min-width:100px;
  border: 1px solid gray;
  text-decoration:none;
}
.context-menu ul {
  position: absolute;
  z-index: 1031;
  line-height: 1.6;
  padding: 0;
  margin: 0;
  box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
  display:none;
  left:98px;
  min-width:100px;
  top:-1px;
  background-color:#dddddd;
  border: 1px solid gray;
  text-decoration:none;
}

.context-menu li {
  position:relative;
}

.context-menu li:hover > ul {
  display:block;
}

.context-menu li {
  padding: 4px 20px;
  margin: 0;
  list-style-type: none;
  cursor: pointer;
  white-space: nowrap;
  color: #333333;
}
.context-menu ul > li:hover {
  background-color: white;
  text-decoration:underline;
}

我希望这能帮到某人