jquery-smartMenu.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. };
  24. var params = $.extend(defaults, options || {});
  25. var htmlCreateMenu = function(datum) {
  26. var dataMenu = datum || data, nameMenu = datum? Math.random().toString(): params.name, htmlMenu = "", htmlCorner = "", clKey = "smart_menu_";
  27. if ($.isArray(dataMenu) && dataMenu.length) {
  28. htmlMenu = '<div id="smartMenu_'+ nameMenu +'" class="'+ clKey +'box">' +
  29. '<div class="'+ clKey +'body">' +
  30. '<ul class="'+ clKey +'ul">';
  31. $.each(dataMenu, function(i, arr) {
  32. if (i) {
  33. htmlMenu = htmlMenu + '<li class="'+ clKey +'li_separate">&nbsp;</li>';
  34. }
  35. if ($.isArray(arr)) {
  36. $.each(arr, function(j, obj) {
  37. var text = obj.text, htmlMenuLi = "", strTitle = "", rand = Math.random().toString().replace(".", "");
  38. if (text) {
  39. if (text.length > params.textLimit) {
  40. text = text.slice(0, params.textLimit) + "…";
  41. strTitle = ' title="'+ obj.text +'"';
  42. }
  43. if ($.isArray(obj.data) && obj.data.length) {
  44. htmlMenuLi = '<li class="'+ clKey +'li" data-hover="true">' + htmlCreateMenu(obj.data) +
  45. '<a href="javascript:" class="'+ clKey +'a"'+ strTitle +' data-key="'+ rand +'"><i class="'+ clKey +'triangle"></i>'+ text +'</a>' +
  46. '</li>';
  47. } else {
  48. htmlMenuLi = '<li class="'+ clKey +'li">' +
  49. '<a href="javascript:" class="'+ clKey +'a"'+ strTitle +' data-key="'+ rand +'">'+ text +'</a>' +
  50. '</li>';
  51. }
  52. htmlMenu += htmlMenuLi;
  53. var objFunc = D.data("func");
  54. objFunc[rand] = obj.func;
  55. D.data("func", objFunc);
  56. }
  57. });
  58. }
  59. });
  60. htmlMenu = htmlMenu + '</ul>' +
  61. '</div>' +
  62. '</div>';
  63. }
  64. return htmlMenu;
  65. }, funSmartMenu = function() {
  66. var idKey = "#smartMenu_", clKey = "smart_menu_", jqueryMenu = $(idKey + params.name);
  67. if (!jqueryMenu.size()) {
  68. $("body").append(htmlCreateMenu());
  69. //事件
  70. $(idKey + params.name +" a").bind("click", function() {
  71. var key = $(this).attr("data-key"),
  72. callback = D.data("func")[key];
  73. if ($.isFunction(callback)) {
  74. callback.call(D.data("trigger"));
  75. }
  76. $.smartMenu.hide();
  77. return false;
  78. });
  79. $(idKey + params.name +" li").each(function() {
  80. var isHover = $(this).attr("data-hover"), clHover = clKey + "li_hover";
  81. $(this).hover(function() {
  82. var jqueryHover = $(this).siblings("." + clHover);
  83. jqueryHover.removeClass(clHover).children("."+ clKey +"box").hide();
  84. jqueryHover.children("."+ clKey +"a").removeClass(clKey +"a_hover");
  85. if (isHover) {
  86. $(this).addClass(clHover).children("."+ clKey +"box").show();
  87. $(this).children("."+ clKey +"a").addClass(clKey +"a_hover");
  88. }
  89. });
  90. });
  91. return $(idKey + params.name);
  92. }
  93. return jqueryMenu;
  94. };
  95. $(this).each(function() {
  96. this.oncontextmenu = function(e) {
  97. //回调
  98. if ($.isFunction(params.beforeShow)) {
  99. params.beforeShow.call(this);
  100. }
  101. e = e || window.event;
  102. //阻止冒泡
  103. e.cancelBubble = true;
  104. if (e.stopPropagation) {
  105. e.stopPropagation();
  106. }
  107. //隐藏当前上下文菜单,确保页面上一次只有一个上下文菜单
  108. $.smartMenu.hide();
  109. var st = D.scrollTop();
  110. var jqueryMenu = funSmartMenu();
  111. if (jqueryMenu) {
  112. jqueryMenu.css({
  113. display: "block",
  114. left: e.clientX + params.offsetX,
  115. top: e.clientY + st + params.offsetY
  116. });
  117. D.data("target", jqueryMenu);
  118. D.data("trigger", this);
  119. //回调
  120. if ($.isFunction(params.afterShow)) {
  121. params.afterShow.call(this);
  122. }
  123. return false;
  124. }
  125. };
  126. });
  127. if (!B.data("bind")) {
  128. B.bind("click", $.smartMenu.hide).data("bind", true);
  129. }
  130. };
  131. $.extend($.smartMenu, {
  132. hide: function() {
  133. var target = D.data("target");
  134. if (target && target.css("display") === "block") {
  135. target.hide();
  136. }
  137. },
  138. remove: function() {
  139. var target = D.data("target");
  140. if (target) {
  141. target.remove();
  142. }
  143. }
  144. });
  145. })(jQuery);