Bootstrap风格的zTree右键菜单


Posted in Javascript onFebruary 17, 2017

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右键菜单,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery版Tab标签切换
Mar 16 Javascript
基于JavaScript 类的使用详解
May 07 Javascript
jQuery基础知识小结
Dec 22 Javascript
JavaScript给url网址进行encode编码的方法
Mar 18 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(二)
Jan 21 Javascript
通过npm引用的vue组件使用详解
Mar 02 Javascript
vue 路由嵌套高亮问题的解决方法
May 17 Javascript
深入浅析Node环境和浏览器的区别
Aug 14 Javascript
javascript防抖函数debounce详解
Jun 11 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
Dec 06 Javascript
详解 javascript对象创建模式
Oct 30 Javascript
详解前端任务构建利器Gulp.js使用指南
Apr 30 Javascript
js仿新浪微博消息发布功能
Feb 17 #Javascript
babel基本使用详解
Feb 17 #Javascript
JS及JQuery对Html内容编码,Html转义
Feb 17 #Javascript
canvas 实现中国象棋
Feb 17 #Javascript
使用vue.js实现checkbox的全选和多个的删除功能
Feb 17 #Javascript
js实现横向拖拽导航条功能
Feb 17 #Javascript
js转换对象为xml
Feb 17 #Javascript
You might like
在WAMP环境下搭建ZendDebugger php调试工具的方法
2011/07/18 PHP
深入PHP数据缓存的使用说明
2013/05/10 PHP
PHP Curl多线程原理实例详解
2013/11/06 PHP
Thinkphp结合ajaxFileUpload实现异步图片传输示例
2017/03/13 PHP
jQuery实现单行文字间歇向上滚动源代码
2013/06/02 Javascript
JQuery异步加载无限下拉框级联功能实现示例
2014/02/19 Javascript
JS本地刷新返回上一页代码
2016/07/25 Javascript
jQuery表单事件实例代码分享
2016/08/18 Javascript
Vue.js 递归组件实现树形菜单(实例分享)
2016/12/21 Javascript
js实现移动端微信页面禁止字体放大
2017/02/16 Javascript
理解 JavaScript EventEmitter
2018/03/29 Javascript
webpack 3.X学习之多页面打包的方法
2018/09/04 Javascript
[01:00:49]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第二场 1月31日
2021/03/11 DOTA
Python写的Socks5协议代理服务器
2014/08/06 Python
Linux下将Python的Django项目部署到Apache服务器
2015/12/24 Python
在Linux命令行终端中使用python的简单方法(推荐)
2017/01/23 Python
Python利用QQ邮箱发送邮件的实现方法(分享)
2017/06/09 Python
python爬虫之模拟登陆csdn的实例代码
2018/05/18 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
Python3.6实现根据电影名称(支持电视剧名称),获取下载链接的方法
2019/08/26 Python
Django框架下静态模板的继承操作示例
2019/11/08 Python
python进行二次方程式计算的实例讲解
2020/12/06 Python
Python 图片处理库exifread详解
2021/02/25 Python
浅析CSS3 用text-overflow解决文字排版问题
2020/10/28 HTML / CSS
加拿大品牌鞋包连锁店:Little Burgundy
2021/02/28 全球购物
西安启天科技有限公司网络工程师面试题笔试题
2016/06/12 面试题
人力资源管理专业学生自我评价
2013/11/20 职场文书
生产副总岗位职责
2013/11/28 职场文书
公务员转正鉴定材料
2014/02/11 职场文书
市级文明单位申报材料
2014/05/07 职场文书
校园会短篇的广播稿
2014/10/21 职场文书
教师节慰问信
2015/02/15 职场文书
大学四年个人总结
2015/03/03 职场文书
感动中国何玥观后感
2015/06/02 职场文书
HR在给员工开具离职证明时,需要注意哪些问题?
2019/07/03 职场文书
详解Redis基本命令与使用场景
2021/06/01 Redis