/ajax/libs/metisMenu/2.0.0/metisMenu.js

https://gitlab.com/Mirros/cdnjs · JavaScript · 228 lines · 172 code · 40 blank · 16 comment · 25 complexity · 0b830eae40f3fcd51d97c1fabf4705b6 MD5 · raw file

  1. /*
  2. * metismenu - v2.0.0
  3. * A jQuery menu plugin
  4. * https://github.com/onokumus/metisMenu
  5. *
  6. * Made by Osman Nuri Okumus
  7. * Under MIT License
  8. */
  9. (function($) {
  10. 'use strict';
  11. function transitionEnd() {
  12. var el = document.createElement('mm');
  13. var transEndEventNames = {
  14. WebkitTransition: 'webkitTransitionEnd',
  15. MozTransition: 'transitionend',
  16. OTransition: 'oTransitionEnd otransitionend',
  17. transition: 'transitionend'
  18. };
  19. for (var name in transEndEventNames) {
  20. if (el.style[name] !== undefined) {
  21. return {
  22. end: transEndEventNames[name]
  23. };
  24. }
  25. }
  26. return false;
  27. }
  28. $.fn.emulateTransitionEnd = function(duration) {
  29. var called = false;
  30. var $el = this;
  31. $(this).one('mmTransitionEnd', function() {
  32. called = true;
  33. });
  34. var callback = function() {
  35. if (!called) {
  36. $($el).trigger($transition.end);
  37. }
  38. };
  39. setTimeout(callback, duration);
  40. return this;
  41. };
  42. var $transition = transitionEnd();
  43. if (!!$transition) {
  44. $.event.special.mmTransitionEnd = {
  45. bindType: $transition.end,
  46. delegateType: $transition.end,
  47. handle: function(e) {
  48. if ($(e.target).is(this)) {
  49. return e.handleObj.handler.apply(this, arguments);
  50. }
  51. }
  52. };
  53. }
  54. var MetisMenu = function(element, options) {
  55. this.$element = $(element);
  56. this.options = $.extend({}, MetisMenu.DEFAULTS, options);
  57. this.transitioning = null;
  58. if (this.options.toggle) {}
  59. //this.show();
  60. this.init();
  61. };
  62. MetisMenu.TRANSITION_DURATION = 350;
  63. MetisMenu.DEFAULTS = {
  64. toggle: true,
  65. doubleTapToGo: false
  66. };
  67. MetisMenu.prototype.init = function() {
  68. var $this = this;
  69. this.$element.find('li.active').has('ul').children('ul').addClass('collapse in');
  70. this.$element.find('li').not('.active').has('ul').children('ul').addClass('collapse');
  71. //add the 'doubleTapToGo' class to active items if needed
  72. if (this.options.doubleTapToGo) {
  73. this.$element.find('li.active').has('ul').children('a').addClass('doubleTapToGo');
  74. }
  75. this.$element.find('li').has('ul').children('a').on('click.metisMenu', function(e) {
  76. var self = $(this);
  77. var $parent = self.parent('li');
  78. var $list = $parent.children('ul');
  79. e.preventDefault();
  80. if ($parent.hasClass('active')) {
  81. $this.hide($list);
  82. } else {
  83. $this.show($list);
  84. }
  85. //Do we need to enable the double tap
  86. if ($this.options.doubleTapToGo) {
  87. //if we hit a second time on the link and the href is valid, navigate to that url
  88. if ($this.doubleTapToGo(self) && self.attr('href') !== '#' && self.attr('href') !== '') {
  89. e.stopPropagation();
  90. document.location = self.attr('href');
  91. return;
  92. }
  93. }
  94. });
  95. };
  96. MetisMenu.prototype.doubleTapToGo = function(elem) {
  97. var $this = this.$element;
  98. //if the class 'doubleTapToGo' exists, remove it and return
  99. if (elem.hasClass('doubleTapToGo')) {
  100. elem.removeClass('doubleTapToGo');
  101. return true;
  102. }
  103. //does not exists, add a new class and return false
  104. if (elem.parent().children('ul').length) {
  105. //first remove all other class
  106. $this.find('.doubleTapToGo').removeClass('doubleTapToGo');
  107. //add the class on the current element
  108. elem.addClass('doubleTapToGo');
  109. return false;
  110. }
  111. };
  112. MetisMenu.prototype.show = function(el) {
  113. var $this = $(el);
  114. var $parent = $this.parent('li');
  115. if (this.transitioning || $this.hasClass('in')) {
  116. return;
  117. }
  118. $parent.addClass('active');
  119. if (this.options.toggle) {
  120. this.hide($parent.siblings().children('ul.in'));
  121. }
  122. $this
  123. .removeClass('collapse')
  124. .addClass('collapsing')
  125. .height(0);
  126. this.transitioning = 1;
  127. var complete = function() {
  128. $this
  129. .removeClass('collapsing')
  130. .addClass('collapse in')
  131. .height('');
  132. this.transitioning = 0;
  133. };
  134. if (!$transition) {
  135. return complete.call(this);
  136. }
  137. $this
  138. .one('mmTransitionEnd', $.proxy(complete, this))
  139. .emulateTransitionEnd(MetisMenu.TRANSITION_DURATION)
  140. .height($this[0].scrollHeight);
  141. };
  142. MetisMenu.prototype.hide = function(el) {
  143. var $this = $(el);
  144. if (this.transitioning || !$this.hasClass('in')) {
  145. return;
  146. }
  147. $this.parent('li').removeClass('active');
  148. $this.height($this.height())[0].offsetHeight;
  149. $this
  150. .addClass('collapsing')
  151. .removeClass('collapse')
  152. .removeClass('in');
  153. this.transitioning = 1;
  154. var complete = function() {
  155. this.transitioning = 0;
  156. $this
  157. .removeClass('collapsing')
  158. .addClass('collapse');
  159. };
  160. if (!$transition) {
  161. return complete.call(this);
  162. }
  163. $this
  164. .height(0)
  165. .one('mmTransitionEnd', $.proxy(complete, this))
  166. .emulateTransitionEnd(MetisMenu.TRANSITION_DURATION);
  167. };
  168. function Plugin(option) {
  169. return this.each(function() {
  170. var $this = $(this);
  171. var data = $this.data('mm');
  172. var options = $.extend({}, MetisMenu.DEFAULTS, $this.data(), typeof option === 'object' && option);
  173. if (!data) {
  174. $this.data('mm', (data = new MetisMenu(this, options)));
  175. }
  176. if (typeof option === 'string') {
  177. data[option]();
  178. }
  179. });
  180. }
  181. var old = $.fn.metisMenu;
  182. $.fn.metisMenu = Plugin;
  183. $.fn.metisMenu.Constructor = MetisMenu;
  184. $.fn.metisMenu.noConflict = function() {
  185. $.fn.metisMenu = old;
  186. return this;
  187. };
  188. })(jQuery);