jquery-smartMenu.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * smartMenu.js 智能上下文菜单插件
  3. * http://www.zhangxinxu.com/
  4. *
  5. * Copyright 2011, zhangxinxu
  6. *
  7. * 2011-05-26 v1.0 编写
  8. * 2011-06-03 v1.1 修复func中this失准问题
  9. * 2011-10-10 v1.2 修复脚本放在<head>标签中层无法隐藏的问题
  10. * 2011-10-30 v1.3 修复IE6~7下二级菜单移到第二项隐藏的问题
  11. */
  12. (function ($) {
  13. var D = $(document).data("func", {});
  14. $.smartMenu = $.noop;
  15. $.fn.smartMenu = function (data, options) {
  16. var B = $("body"), defaults = {
  17. name: "",
  18. offsetX: 2,
  19. offsetY: 2,
  20. textLimit: 6,
  21. beforeShow: $.noop,
  22. afterShow: $.noop,
  23. clickType:"right"
  24. };
  25. var params = $.extend(defaults, options || {});//参数
  26. var htmlCreateMenu = function (datum) {
  27. var dataMenu = datum || data, nameMenu = datum ? Math.random().toString() : params.name, htmlMenu = "", htmlCorner = "", clKey = "smart_menu_";
  28. if ($.isArray(dataMenu) && dataMenu.length) {
  29. htmlMenu = '<div id="smartMenu_' + nameMenu + '" class="' + clKey + 'box">' +
  30. '<div class="' + clKey + 'body">' +
  31. '<ul class="' + clKey + 'ul">';
  32. $.each(dataMenu, function (i, arr) {
  33. if (i) {
  34. htmlMenu = htmlMenu + '<li class="' + clKey + 'li_separate">&nbsp;</li>';
  35. }
  36. if ($.isArray(arr)) {
  37. $.each(arr, function (j, obj) {
  38. var text = obj.text, htmlMenuLi = "", strTitle = "", rand = Math.random().toString().replace(".", "");
  39. if (text) {
  40. if (text.length > params.textLimit) {
  41. text = text.slice(0, params.textLimit) + "…";
  42. strTitle = ' title="' + obj.text + '"';
  43. }
  44. if ($.isArray(obj.data) && obj.data.length) {
  45. htmlMenuLi = '<li class="' + clKey + 'li" data-hover="true">' + htmlCreateMenu(obj.data) +
  46. '<a href="javascript:" class="' + clKey + 'a"' + strTitle + ' data-key="' + rand + '"><i class="' + clKey + 'triangle"></i>' + text + '</a>' +
  47. '</li>';
  48. } else {
  49. htmlMenuLi = '<li class="' + clKey + 'li">' +
  50. '<a href="javascript:" class="' + clKey + 'a"' + strTitle + ' data-key="' + rand + '">' + text + '</a>' +
  51. '</li>';
  52. }
  53. htmlMenu += htmlMenuLi;
  54. var objFunc = D.data("func");
  55. objFunc[rand] = obj.func;
  56. D.data("func", objFunc);
  57. }
  58. });
  59. }
  60. });
  61. htmlMenu = htmlMenu + '</ul>' +
  62. '</div>' +
  63. '</div>';
  64. }
  65. return htmlMenu;
  66. }, funSmartMenu = function () {
  67. var idKey = "#smartMenu_", clKey = "smart_menu_", jqueryMenu = $(idKey + params.name);
  68. if (!jqueryMenu.size()) {
  69. $("body").append(htmlCreateMenu());
  70. //事件
  71. $(idKey + params.name + " a").bind("click", function () {
  72. var key = $(this).attr("data-key"),
  73. callback = D.data("func")[key];
  74. if ($.isFunction(callback)) {
  75. callback.call(D.data("trigger"));
  76. }
  77. $.smartMenu.hide();
  78. return false;
  79. });
  80. $(idKey + params.name + " li").each(function () {
  81. var isHover = $(this).attr("data-hover"), clHover = clKey + "li_hover";
  82. $(this).hover(function () {
  83. var jqueryHover = $(this).siblings("." + clHover);
  84. jqueryHover.removeClass(clHover).children("." + clKey + "box").hide();
  85. jqueryHover.children("." + clKey + "a").removeClass(clKey + "a_hover");
  86. if (isHover) {
  87. $(this).addClass(clHover).children("." + clKey + "box").show();
  88. $(this).children("." + clKey + "a").addClass(clKey + "a_hover");
  89. }
  90. });
  91. });
  92. return $(idKey + params.name);
  93. }
  94. return jqueryMenu;
  95. };
  96. $(this).each(function () {
  97. this.oncontextmenu = function (e) {
  98. //回调
  99. if ($.isFunction(params.beforeShow)) {
  100. params.beforeShow.call(this);
  101. }
  102. e = e || window.event;
  103. //阻止冒泡
  104. e.cancelBubble = true;
  105. if (e.stopPropagation) {
  106. e.stopPropagation();//防止事件再次传播
  107. }
  108. //隐藏当前上下文菜单,确保页面上一次只有一个上下文菜单
  109. $.smartMenu.hide();
  110. var st = D.scrollTop();
  111. var jqueryMenu = funSmartMenu();
  112. if (jqueryMenu) {
  113. jqueryMenu.css({
  114. display: "block",
  115. left: e.clientX + params.offsetX,
  116. top: e.clientY + st + params.offsetY
  117. });
  118. D.data("target", jqueryMenu);
  119. D.data("trigger", this);
  120. //回调
  121. if ($.isFunction(params.afterShow)) {
  122. params.afterShow.call(this);
  123. }
  124. return false;
  125. }
  126. };
  127. });
  128. if (!B.data("bind")) {
  129. B.bind("click", $.smartMenu.hide).data("bind", true);
  130. }
  131. };
  132. $.extend($.smartMenu, {
  133. hide: function () {
  134. var target = D.data("target");
  135. if (target && target.css("display") === "block") {
  136. target.hide();
  137. }
  138. },
  139. remove: function () {
  140. var target = D.data("target");
  141. if (target) {
  142. target.remove();
  143. }
  144. }
  145. });
  146. })(jQuery);