Bootstrap风格的zTree右键菜单
程序员文章站
2023-12-06 11:54:16
html:
<%-- 右键菜单 --%>
html:
<%-- 右键菜单 --%> <div id="ztreerightmenucontainer" style="z-index: 9999;"> <%-- 层级 0 --%> <ul class="dropdown-menu" role="menu" level="0"> <%-- 通过给菜单项添加样式“haschildren”并在li标签下添加菜单结构即可扩展子级菜单 --%> <li class="haschildren"><a tabindex="-1" action="refreshztreeobj">刷新</a> <ul class="dropdown-menu" role="menu" level="1"> <li><a tabindex="-1">将数据库复制到不同的主机/数据库</a></li> <li><a tabindex="-1">创建数据库</a></li> <li><a tabindex="-1">改变数据库</a></li> <li><a tabindex="-1">新数据搜索</a></li> <li><a tabindex="-1">创/建</a></li> <li><a tabindex="-1">更多数据库操作</a></li> <li class="divider"></li> <li><a tabindex="-1">备份/导出</a></li> <li><a tabindex="-1">导入</a></li> <li class="divider"></li> <li><a tabindex="-1">在创建数据库架构html</a></li> </ul> </li> </ul> <%-- 层级 1 --%> <ul class="dropdown-menu" role="menu" level="1"> <li><a tabindex="-1">将数据库复制到不同的主机/数据库</a></li> <li><a tabindex="-1">创建数据库</a></li> <li><a tabindex="-1">改变数据库</a></li> <li><a tabindex="-1">新数据搜索</a></li> <li><a tabindex="-1">创/建</a></li> <li><a tabindex="-1">更多数据库操作</a></li> <li class="divider"></li> <li><a tabindex="-1">备份/导出</a></li> <li><a tabindex="-1">导入</a></li> <li class="divider"></li> <li><a tabindex="-1">在创建数据库架构html</a></li> </ul> <%-- 层级 2 --%> <ul class="dropdown-menu" role="menu" level="2"> <li><a tabindex="-1">创建表</a></li> <li><a tabindex="-1">将表复制到不同的主机/数据库</a></li> <li><a tabindex="-1">数据搜索</a></li> <li class="divider"></li> <li><a tabindex="-1">计划备份</a></li> <li><a tabindex="-1">备份表作为sql转储</a></li> </ul> </div>
css:
/* 右键菜单 - start */ .dropdown-menu .dropdown-menu { position: absolute; top: -9px; left: 100%; } .dropdown-menu li { position: relative; } .dropdown-menu li.haschildren:before { content: ''; position: absolute; top: 50%; right: 8px; width: 0; height: 0; margin-top: -5px; border-style: solid; border-color: transparent transparent transparent rgba(0, 0, 0, 0.5); border-width: 5px 0 5px 5px; pointer-events: none; } .dropdown-menu li.haschildren:hover > .dropdown-menu { display: block; } /* 右键菜单 - end */
js:
/* 以下为右键菜单插件(bootstrap风格) */ ;(function ($) { 'use strict'; /* contextmenu class definition * ============================ */ var toggle = '[data-toggle="context"]'; var contextmenu = function (element, options) { this.$element = $(element); this.before = options.before || this.before; this.onitem = options.onitem || this.onitem; this.scopes = options.scopes || null; if (options.target) { this.$element.data('target', options.target); } this.listen(); }; contextmenu.prototype = { constructor: contextmenu , show: function (e) { var $menu , evt , tp , items , relatedtarget = {relatedtarget: this, target: e.currenttarget}; if (this.isdisabled()) return; this.closemenu(); if (this.before.call(this, e, $(e.currenttarget)) === false) return; $menu = this.getmenu(); $menu.trigger(evt = $.event('show.bs.context', relatedtarget)); tp = this.getposition(e, $menu); items = 'li:not(.divider)'; $menu.attr('style', '') .css(tp) .addclass('open') .on('click.context.data-api', items, $.proxy(this.onitem, this, $(e.currenttarget))) .trigger('shown.bs.context', relatedtarget); // delegating the `closemenu` only on the currently opened menu. // this prevents other opened menus from closing. $('html') .on('click.context.data-api', $menu.selector, $.proxy(this.closemenu, this)); return false; } , closemenu: function (e) { var $menu , evt , items , relatedtarget; $menu = this.getmenu(); if (!$menu.hasclass('open')) return; relatedtarget = {relatedtarget: this}; $menu.trigger(evt = $.event('hide.bs.context', relatedtarget)); items = 'li:not(.divider)'; $menu.removeclass('open') .off('click.context.data-api', items) .trigger('hidden.bs.context', relatedtarget); $('html') .off('click.context.data-api', $menu.selector); // don't propagate click event so other currently // opened menus won't close. if (e) { e.stoppropagation(); } } , keydown: function (e) { if (e.which == 27) this.closemenu(e); } , before: function (e) { return true; } , onitem: function (e) { return true; } , listen: function () { this.$element.on('contextmenu.context.data-api', this.scopes, $.proxy(this.show, this)); $('html').on('click.context.data-api', $.proxy(this.closemenu, this)); $('html').on('keydown.context.data-api', $.proxy(this.keydown, this)); } , destroy: function () { this.$element.off('.context.data-api').removedata('context'); $('html').off('.context.data-api'); } , isdisabled: function () { return this.$element.hasclass('disabled') || this.$element.attr('disabled'); } , getmenu: function () { var selector = this.$element.data('target') , $menu; if (!selector) { selector = this.$element.attr('href'); selector = selector && selector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7 } $menu = $(selector); return $menu && $menu.length ? $menu : this.$element.find(selector); } , getposition: function (e, $menu) { var mousex = e.clientx , mousey = e.clienty , boundsx = $(window).width() , boundsy = $(window).height() , menuwidth = $menu.find('.dropdown-menu').outerwidth() , menuheight = $menu.find('.dropdown-menu').outerheight() , tp = {"position": "absolute", "z-index": 9999} , y, x, parentoffset; if (mousey + menuheight > boundsy) { y = {"top": mousey - menuheight + $(window).scrolltop()}; } else { y = {"top": mousey + $(window).scrolltop()}; } if ((mousex + menuwidth > boundsx) && ((mousex - menuwidth) > 0)) { x = {"left": mousex - menuwidth + $(window).scrollleft()}; } else { x = {"left": mousex + $(window).scrollleft()}; } // if context-menu's parent is positioned using absolute or relative positioning, // the calculated mouse position will be incorrect. // adjust the position of the menu by its offset parent position. parentoffset = $menu.offsetparent().offset(); x.left = x.left - parentoffset.left; y.top = y.top - parentoffset.top; return $.extend(tp, y, x); } }; /* context menu plugin definition * ========================== */ $.fn.contextmenu = function (option, e) { return this.each(function () { var $this = $(this) , data = $this.data('context') , options = (typeof option == 'object') && option; if (!data) $this.data('context', (data = new contextmenu($this, options))); if (typeof option == 'string') data[option].call(data, e); }); }; $.fn.contextmenu.constructor = contextmenu; /* apply to standard context menu elements * =================================== */ $(document) .on('contextmenu.context.data-api', function () { $(toggle).each(function () { var data = $(this).data('context'); if (!data) return; data.closemenu(); }); }) .on('contextmenu.context.data-api', toggle, function (e) { $(this).contextmenu('show', e); e.preventdefault(); e.stoppropagation(); }); }(jquery));
/* 以下方法是通过上面的js插件封装的方法 */ /* parentnode(ztree容器 || 指定的节点) */ function initztreerightmenu(parentnode) { //树形菜单右击事件 $('li, a', $(parentnode)).contextmenu({ target: '#ztreerightmenucontainer', //此设置项是ztree的容器 before: function (e, element, target) { //当前右击节点id var selectedid = element[0].tagname == 'li' ? element.attr('id') : element.parent().attr('id'); //根据节点id获取当前节点详细信息 curselectnode = ztreeobj.getnodebytid(selectedid); //当前节点的层级 var level = curselectnode.level; level = 0; //选中当前右击节点 ztreeobj.selectnode(curselectnode); //根据当前节点层级显示相应的菜单 $('#ztreerightmenucontainer ul.dropdown-menu[level="' + level + '"]').removeclass('hide').siblings().addclass('hide'); }, onitem: function (context, e) { var action = $(e.target).attr('action'); this.closemenu(); if (action) { ztreerightmenufuns[action](); } } }); }
步骤:
1、引入ztree相关js、css文件(以我自己的项目为例:jquery.ztree.all-3.5.min.js,ztreestyle.css);
2、将上面给出的右键菜单插件另存为js文件引入页面(以我自己的项目为例:bscontextmenu.js)
3、在页面初始化ztree之后,调用上面的方法:initztreerightmenu('#schemamgrtree'); // ‘#schemamgrtree' 是我自己项目的ztree容器id
备注:
1、假如ztree中有异步载入的节点(以我自己项目为例:ztree中有部分节点是展开了父节点之后才加载的,像这种情况则需要在 ztree 的 onexpandfun 里面绑定当前节点的子节点)
function onexpandfun(event, treeid, treenode) { /* 展开当前节点执行的代码.... *///绑定当前展开节点的子节点右击事件 initztreerightmenu('#' + treenode.tid); //treenode.tid 是当前展开节点的id }
以上所述是小编给大家介绍的bootstrap风格的ztree右键菜单,希望对大家有所帮助