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 相关文章推荐
a标签的href和onclick 的事件的区别介绍
Jul 26 Javascript
jQuery动画效果-slideUp slideDown上下滑动示例代码
Aug 28 Javascript
js使用post 方式打开新窗口
Feb 26 Javascript
JavaScript中Number.MAX_VALUE属性的使用方法
Jun 04 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
Sep 18 Javascript
常用js,css文件统一加载方法(推荐) 并在加载之后调用回调函数
Sep 23 Javascript
老生常谈Javascript中的原型和this指针
Oct 09 Javascript
Bootstrap基本插件学习笔记之按钮(21)
Dec 08 Javascript
微信小程序实现下拉菜单切换效果
Mar 30 Javascript
详解js 创建对象的几种方法
Mar 08 Javascript
基于vue手写tree插件的那点事儿
Aug 20 Javascript
vue渲染方式render和template的区别
Jun 05 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 类型转换函数intval
2009/06/20 PHP
php实现保存submit内容之后禁止刷新
2014/03/19 PHP
php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
2020/04/05 PHP
php实现singleton()单例模式实例
2014/11/06 PHP
PHP实现货币换算的方法
2014/11/29 PHP
PHP结合jQuery插件ajaxFileUpload实现异步上传文件实例
2020/08/17 PHP
使用php+swoole对client数据实时更新(一)
2016/01/07 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
PHP论坛实现积分系统的思路代码详解
2020/06/01 PHP
window.ActiveXObject使用说明
2010/11/08 Javascript
jQuery使用attr()方法同时设置多个属性值用法实例
2015/03/26 Javascript
jQuery实现仿美橙互联两级导航菜单效果完整实例
2015/09/17 Javascript
GitHub上一些实用的JavaScript的文件压缩解压缩库推荐
2016/03/13 Javascript
简介EasyUI datagrid editor combogrid搜索框的实现
2016/04/01 Javascript
jQuery实现的小图列表,大图展示效果幻灯片示例
2016/10/25 Javascript
使用express搭建一个简单的查询服务器的方法
2018/02/09 Javascript
Node.js中的child_process模块详解
2018/06/08 Javascript
Bootstrap的aria-label和aria-labelledby属性实例详解
2018/11/02 Javascript
谈谈JavaScript中super(props)的重要性
2019/02/12 Javascript
手把手15分钟搭一个企业级脚手架
2019/09/16 Javascript
angular inputNumber指令输入框只能输入数字的实现
2019/12/03 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
前端使用crypto.js进行加密的函数代码
2020/08/16 Javascript
通过python下载FTP上的文件夹的实现代码
2013/02/10 Python
Python os模块介绍
2014/11/30 Python
Python获取网页上图片下载地址的方法
2015/03/11 Python
python实现自动登录人人网并采集信息的方法
2015/06/28 Python
pytorch + visdom 处理简单分类问题的示例
2018/06/04 Python
python读取和保存图片5种方法对比
2018/09/12 Python
BP神经网络原理及Python实现代码
2018/12/18 Python
Python中最大递归深度值的探讨
2019/03/05 Python
django项目简单调取百度翻译接口的方法
2019/08/06 Python
python自动化工具之pywinauto实例详解
2019/08/26 Python
美国排名第一的葡萄酒俱乐部:Firstleaf Wine Club
2020/01/02 全球购物
个人考核材料
2014/05/15 职场文书
2015年信贷员工作总结
2015/04/28 职场文书