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 相关文章推荐
javascript的onchange事件与jQuery的change()方法比较
Sep 28 Javascript
javascript instanceof 内部机制探析
Oct 15 Javascript
javascript 随机展示头像实现代码
Dec 06 Javascript
js 获取时间间隔实现代码
May 12 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
Mar 09 Javascript
自动化测试读写64位操作系统的注册表
Aug 15 Javascript
js微信扫描二维码登录网站技术原理
Dec 01 Javascript
Three.js的使用及绘制基础3D图形详解
Apr 27 Javascript
利用vue + element实现表格分页和前端搜索的方法
Dec 25 Javascript
jQuery解析json格式数据示例
Sep 01 jQuery
详解Ubuntu安装angular-cli遇到的坑
Sep 08 Javascript
vue组件tabbar使用方法详解
Nov 06 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
php中数据的批量导入(csv文件)
2006/10/09 PHP
discuz7 phpMysql操作类
2009/06/21 PHP
php+mysqli实现批量替换数据库表前缀的方法
2014/12/29 PHP
PHP随机生成信用卡卡号的方法
2015/03/23 PHP
使用JavaScript创建新样式表和新样式规则
2016/06/14 PHP
javascript向flash swf文件传递参数值注意细节
2012/12/11 Javascript
求数组最大最小值方法适用于任何数组
2013/08/16 Javascript
javascript 获取iframe里页面中元素值的方法
2014/02/17 Javascript
原生JavaScript生成GUID的实现示例
2014/09/05 Javascript
Javascript writable特性介绍
2015/02/27 Javascript
jQuery跨域问题解决方案
2015/08/03 Javascript
nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证示例
2016/12/30 NodeJs
详解Vue路由开启keep-alive时的注意点
2017/06/20 Javascript
VUE中v-model和v-for指令详解
2017/06/23 Javascript
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
vue-router命名路由和编程式路由传参讲解
2019/01/19 Javascript
浅析vue中的provide / inject 有什么用处
2019/11/10 Javascript
详解vue或uni-app的跨域问题解决方案
2020/02/21 Javascript
javaScript实现一个队列的方法
2020/07/14 Javascript
Python基于twisted实现简单的web服务器
2014/09/29 Python
python实现数据预处理之填充缺失值的示例
2017/12/22 Python
Java实现的执行python脚本工具类示例【使用jython.jar】
2018/03/29 Python
python3+PyQt5自定义视图详解
2018/04/24 Python
Python进阶之全面解读高级特性之切片
2019/02/19 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
2020/02/07 Python
python 将视频 通过视频帧转换成时间实例
2020/04/23 Python
Python实现验证码识别
2020/06/15 Python
通过代码实例了解Python sys模块
2020/09/14 Python
使用python爬取抖音app视频的实例代码
2020/12/01 Python
远程教育心得体会
2014/01/03 职场文书
美德少年事迹材料
2014/01/23 职场文书
访谈节目策划方案
2014/05/15 职场文书
班主任开场白
2015/06/01 职场文书
地道战观后感500字
2015/06/04 职场文书
2016高考寄语或鼓励的话语
2015/12/04 职场文书
详解Mysql事务并发(脏读、不可重复读、幻读)
2022/04/29 MySQL