前言
使用$.fn.menu.defaults重写默认值对象。下载该插件翻译源码
菜单组件通常用于快捷菜单。他是构建其他菜单组件的必备基础组件。比如:menubutton和splitbutton。它还可以用于导航和执行命令。
源码
/** * jQuery EasyUI 1.3.2 * * 翻译:qq 1364386878 * *g=this p=g.options */ (function ($) { //初始化 function _init(target) { $(target).appendTo("body"); $(target).addClass("menu-top"); $(document).unbind(".menu").bind("mousedown.menu", function (e) { var visible = $("body>div.menu:visible"); var m = $(e.target).closest("div.menu", visible); if (m.length) { return; } $("body>div.menu-top:visible").menu("hide"); }); var menus = adjust($(target)); for (var i = 0; i < menus.length; i++) { wrapMenu(menus[i]); } //递归获取菜单项 function adjust(menu) { var menus = []; menu.addClass("menu"); if (!menu[0].style.width) { menu[0].autowidth = true; } menus.push(menu); if (!menu.hasClass("menu-content")) { menu.children("div").each(function () { var divchild = $(this).children("div"); if (divchild.length) { divchild.insertAfter(target); this.submenu = divchild; var mm = adjust(divchild); menus = menus.concat(mm); } }); } return menus; }; function wrapMenu(menu) { if (!menu.hasClass("menu-content")) { menu.children("div").each(function () { var item = $(this); if (item.hasClass("menu-sep")) { } else { var options = $.extend({}, $.parser.parseOptions(this, ["name", "iconCls", "href"]), { disabled: (item.attr("disabled") ? true : undefined) }); item.attr("name", options.name || "").attr("href", options.href || ""); var text = item.addClass("menu-item").html(); item.empty().append($("<div class=\"menu-text\"></div>").html(text)); if (options.iconCls) { $("<div class=\"menu-icon\"></div>").addClass(options.iconCls).appendTo(item); } if (options.disabled) { _enableItem(target, item[0], true); } if (item[0].submenu) { $("<div class=\"menu-rightarrow\"></div>").appendTo(item); } item._outerHeight(22); _f(target, item); } }); $("<div class=\"menu-line\"></div>").prependTo(menu); } _10(target, menu); menu.hide(); menuEvent(target, menu); }; }; function _10(target, parm) { var options = $.data(target, "menu").options; var d = parm.css("display"); parm.css({ display: "block", left: -10000 }); var width = parm._outerWidth(); var menuwidth = 0; parm.find("div.menu-text").each(function () { if (menuwidth < $(this)._outerWidth()) { menuwidth = $(this)._outerWidth(); } }); menuwidth += 65; parm._outerWidth(Math.max(width, menuwidth, options.minWidth)); parm.css("display", d); }; //菜单事件 function menuEvent(target, menu2) { var menu = $.data(target, "menu"); menu2.unbind(".menu").bind("mouseenter.menu", function () { if (menu.timer) { clearTimeout(menu.timer); menu.timer = null; } }).bind("mouseleave.menu", function () { menu.timer = setTimeout(function () { _hide(target);//隐藏菜单 }, 100); }); }; //菜单项事件 function _f(target, item) { item.unbind(".menu"); item.bind("click.menu", function () { if ($(this).hasClass("menu-item-disabled")) { return; } if (!this.submenu) { _hide(target); var _1d = $(this).attr("href"); if (_1d) { location.href = _1d; } } var _1e = $(target).menu("getItem", this); $.data(target, "menu").options.onClick.call(target, _1e); }).bind("mouseenter.menu", function (e) { item.siblings().each(function () { if (this.submenu) { hideMenu(this.submenu); } $(this).removeClass("menu-active"); }); item.addClass("menu-active"); if ($(this).hasClass("menu-item-disabled")) { item.addClass("menu-active-disabled"); return; } var _1f = item[0].submenu; if (_1f) { $(target).menu("show", { menu: _1f, parent: item }); } }).bind("mouseleave.menu", function (e) { item.removeClass("menu-active menu-active-disabled"); var menu = item[0].submenu; if (menu) { if (e.pageX >= parseInt(menu.css("left"))) { item.addClass("menu-active"); } else { hideMenu(menu); } } else { item.removeClass("menu-active"); } }); }; //隐藏菜单 function _hide(target) { var menu = $.data(target, "menu"); if (menu) { if ($(target).is(":visible")) { hideMenu($(target)); menu.options.onHide.call(target); } } return false; }; // //显示菜单到指定的位置pos(left/right) function _showmenu(target, pos) { var left, top; var menu = $(pos.menu || target); if (menu.hasClass("menu-top")) { var options = $.data(target, "menu").options; left = options.left; top = options.top; if (pos.alignTo) { var at = $(pos.alignTo); left = at.offset().left; top = at.offset().top + at._outerHeight(); } if (pos.left != undefined) { left = pos.left; } if (pos.top != undefined) { top = pos.top; } if (left + menu.outerWidth() > $(window)._outerWidth() + $(document)._scrollLeft()) { left = $(window)._outerWidth() + $(document).scrollLeft() - menu.outerWidth() - 5; } if (top + menu.outerHeight() > $(window)._outerHeight() + $(document).scrollTop()) { top -= menu.outerHeight(); } } else { var parent = pos.parent; left = parent.offset().left + parent.outerWidth() - 2; if (left + menu.outerWidth() + 5 > $(window)._outerWidth() + $(document).scrollLeft()) { left = parent.offset().left - menu.outerWidth() + 2; } var top = parent.offset().top - 3; if (top + menu.outerHeight() > $(window)._outerHeight() + $(document).scrollTop()) { top = $(window)._outerHeight() + $(document).scrollTop() - menu.outerHeight() - 5; } } menu.css({ left: left, top: top }); menu.show(0, function () { if (!menu[0].shadow) { menu[0].shadow = $("<div class=\"menu-shadow\"></div>").insertAfter(menu); } menu[0].shadow.css({ display: "block", zIndex: $.fn.menu.defaults.zIndex++, left: menu.css("left"), top: menu.css("top"), width: menu.outerWidth(), height: menu.outerHeight() }); menu.css("z-index", $.fn.menu.defaults.zIndex++); if (menu.hasClass("menu-top")) { $.data(menu[0], "menu").options.onShow.call(menu[0]); } }); }; //隐藏菜单项 function hideMenu(menu) { if (!menu) { return; } _hideshadow(menu); menu.find("div.menu-item").each(function () { if (this.submenu) { hideMenu(this.submenu); } $(this).removeClass("menu-active"); }); function _hideshadow(m) { m.stop(true, true); if (m[0].shadow) { m[0].shadow.hide(); } m.hide(); }; }; //查找的指定菜单项 function _findItem(target, text) { var item = null; var tmp = $("<div></div>"); function find(parentMenu) { parentMenu.children("div.menu-item").each(function () { var item = $(target).menu("getItem", this); var s = tmp.empty().html(item.text).text(); if (text == $.trim(s)) { item = item; } else { if (this.submenu && !item) { find(this.submenu); } } }); }; find($(target)); tmp.remove(); return item; }; //启用禁用菜单项 function _enableItem(target, itemEl, disabled) { var t = $(itemEl); if (disabled) { t.addClass("menu-item-disabled"); if (itemEl.onclick) { itemEl.onclick1 = itemEl.onclick; itemEl.onclick = null; } } else { t.removeClass("menu-item-disabled"); if (itemEl.onclick1) { itemEl.onclick = itemEl.onclick1; itemEl.onclick1 = null; } } }; //追加新的菜单项 function menuppendItem(target, options) { var parm = $(target); if (options.parent) { if (!options.parent.submenu) { var menu = $("<div class=\"menu\"><div class=\"menu-line\"></div></div>").appendTo("body"); menu[0].autowidth = true; menu.hide(); options.parent.submenu = menu; $("<div class=\"menu-rightarrow\"></div>").appendTo(options.parent); } parm = options.parent.submenu; } var item = $("<div class=\"menu-item\"></div>").appendTo(parm); $("<div class=\"menu-text\"></div>").html(options.text).appendTo(item); if (options.iconCls) { $("<div class=\"menu-icon\"></div>").addClass(options.iconCls).appendTo(item); } if (options.id) { item.attr("id", options.id); } if (options.href) { item.attr("href", options.href); } if (options.name) { item.attr("name", options.name); } if (options.onclick) { if (typeof options.onclick == "string") { item.attr("onclick", options.onclick); } else { item[0].onclick = eval(options.onclick); } } if (options.handler) { item[0].onclick = eval(options.handler); } _f(target, item); if (options.disabled) { _enableItem(target, item[0], true); } menuEvent(target, parm); _10(target, parm); }; //移除指定的菜单项 function _removeItem(target, itemEl) { function remove(el) { if (el.submenu) { el.submenu.children("div.menu-item").each(function () { remove(this); }); var shadow = el.submenu[0].shadow; if (shadow) { shadow.remove(); } el.submenu.remove(); } $(el).remove(); }; remove(itemEl); }; //销毁菜单 function textestroy(target) { $(target).children("div.menu-item").each(function () { _removeItem(target, this); }); if (target.shadow) { target.shadow.remove(); } $(target).remove(); }; //实例化菜单 $.fn.menu = function (target, parm) { if (typeof target == "string") { return $.fn.menu.methods[target](this, parm); } target = target || {}; return this.each(function () { var menu = $.data(this, "menu"); if (menu) { $.extend(menu.options, target); } else { menu = $.data(this, "menu", { options: $.extend({}, $.fn.menu.defaults, $.fn.menu.parseOptions(this), target) }); _init(this); } $(this).css({ left: menu.options.left, top: menu.options.top }); }); }; //默认的方法 $.fn.menu.methods = { //返回属性对象 options: function (jq) { return $.data(jq[0], "menu").options; }, //显示菜单到指定的位置pos(left/right) show: function (jq, pos) { return jq.each(function () { _showmenu(this, pos); }); }, //隐藏菜单 hide: function (jq) { return jq.each(function () { _hide(this); }); }, //销毁菜单 destroy: function (jq) { return jq.each(function () { textestroy(this); }); }, //设置指定菜单项的文本 'param'参数包含2个属性:target:DOM对象,要设置值的菜单项。 text: 字符串,要设置的新文本值。 setText: function (jq, param) { return jq.each(function () { $(param.target).children("div.menu-text").html(param.text); }); }, //设置指定菜单项图标。'param'参数包含2个属性: target:DOM对象,要设置的菜单项。 iconCls:新的图标CSS类ID。 setIcon: function (jq, param) { return jq.each(function () { var item = $(this).menu("getItem", param.target); if (item.iconCls) { $(item.target).children("div.menu-icon").removeClass(item.iconCls).addClass(param.iconCls); } else { $("<div class=\"menu-icon\"></div>").addClass(param.iconCls).appendTo(param.target); } }); }, //获取指定的菜单项。得到的是一个菜单项的DOM元素。下面的例子展示了如何根据ID获取指定的项: getItem: function (jq, itemEl) { var t = $(itemEl); var item = { target: itemEl, id: t.attr("id"), text: $.trim(t.children("div.menu-text").html()), disabled: t.hasClass("menu-item-disabled"), href: t.attr("href"), name: t.attr("name"), onclick: itemEl.onclick }; var submenu = t.children("div.menu-icon"); if (submenu.length) { var cc = []; var aa = submenu.attr("class").split(" "); for (var i = 0; i < aa.length; i++) { if (aa[i] != "menu-icon") { cc.push(aa[i]); } } item.iconCls = cc.join(" "); } return item; }, //查找的指定菜单项,返回的对象和getItem方法是一样的。 findItem: function (jq, text) { return _findItem(jq[0], text); }, //追加新的菜单项,'options'参数代表新菜单项属性。默认情况下添加的项在菜单项的顶部。追加一个子菜单项, //'parent'属性应该设置指定的父项元素,并且该父项元素必须是已经定义在页面上的。 appendItem: function (jq, options) { return jq.each(function () { menuppendItem(this, options); }); }, //移除指定的菜单项。 removeItem: function (jq, itemEl) { return jq.each(function () { _removeItem(this, itemEl); }); }, //启用菜单项 enableItem: function (jq, itemEl) { return jq.each(function () { _enableItem(this, itemEl, false); }); }, //禁用菜单项 disableItem: function (jq, itemEl) { return jq.each(function () { _enableItem(this, itemEl, true); }); } }; $.fn.menu.parseOptions = function (target) { return $.extend({}, $.parser.parseOptions(target, ["left", "top", { minWidth: "number" }])); }; //菜单默认属性+事件 $.fn.menu.defaults = { zIndex: 110000,//菜单z-index样式,增加它的值 left: 0,//菜单的左边距位置 top: 0,//菜单的上边距位置 minWidth: 120,//菜单的最小宽度 //在菜单显示之后触发 onShow: function () { }, //在菜单隐藏之后触发 onHide: function () { }, //在菜单项被点击的时候触发。下面的例子显示了如何处理所有菜单项的点击 onClick: function (item) { } }; })(jQuery);
示例代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Menu - jQuery EasyUI Demo</title> <link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="../../themes/icon.css"> <link rel="stylesheet" type="text/css" href="../demo.css"> <script type="text/javascript" src="../../jquery-1.8.0.min.js"></script> <script src="../../plugins2/jquery.parser.js"></script> <script src="../../plugins2/jquery.menu.js"></script> </head> <body> <h2>Basic Menu</h2> <div class="demo-info"> <div class="demo-tip icon-tip"></div> <div>Right click on page to display menu.</div> </div> <div style="margin:10px 0;"></div> <div id="mm" class="easyui-menu" style="width:120px;"> <div onclick="javascript:alert('new')">New</div> <div> <span>Open</span> <div style="width:150px;"> <div><b>Word</b></div> <div>Excel</div> <div>PowerPoint</div> <div> <span>M1</span> <div style="width:120px;"> <div>sub1</div> <div>sub2</div> <div> <span>Sub</span> <div style="width:80px;"> <div onclick="javascript:alert('sub21')">sub21</div> <div>sub22</div> <div>sub23</div> </div> </div> <div>sub3</div> </div> </div> <div> <span>Window Demos</span> <div style="width:120px;"> <div data-options="href:'window.html'">Window</div> <div data-options="href:'dialog.html'">Dialog</div> <div><a href="http://www.jeasyui.com" target="_blank">EasyUI</a></div> </div> </div> </div> </div> <div data-options="iconCls:'icon-save'">Save</div> <div data-options="iconCls:'icon-print',disabled:true">Print</div> <div class="menu-sep"></div> <div>Exit</div> </div> <script> $(function(){ $(document).bind('contextmenu',function(e){ e.preventDefault(); $('#mm').menu('show', { left: e.pageX, top: e.pageY }); }); }); </script> </body> </html>