jquery-sliding-menu.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. *
  3. * jQuery Sliding Menu Plugin
  4. * Mobile app list-style navigation in the browser
  5. *
  6. * Written by Ali Zahid
  7. * http://designplox.com/jquery-sliding-menu
  8. *
  9. */
  10. (function($)
  11. {
  12. var usedIds = [];
  13. $.fn.slidingMenu = function(options)
  14. {
  15. var selector = this.selector;
  16. var rtl = false;
  17. if($('html').data('textdirection') == "rtl"){
  18. rtl = true;
  19. }
  20. var settings = $.extend(
  21. {
  22. dataJSON: false,
  23. backLabel: 'Back'
  24. }, options);
  25. return this.each(function()
  26. {
  27. var self = this,
  28. menu = $(self),
  29. data;
  30. if (menu.hasClass('sliding-menu'))
  31. {
  32. updateWidth();
  33. return;
  34. }
  35. var menuWidth = menu.outerWidth();
  36. // Updated menu widh
  37. //var menuWidth = menu[0].offsetWidth;
  38. if (settings.dataJSON)
  39. {
  40. data = processJSON(settings.dataJSON);
  41. }
  42. else
  43. {
  44. data = process(menu);
  45. }
  46. menu.empty().addClass('sliding-menu');
  47. var rootPanel;
  48. if (settings.dataJSON)
  49. {
  50. $(data).each(function(index, item)
  51. {
  52. var panel = $('<ul></ul>');
  53. if (item.root)
  54. {
  55. rootPanel = '#' + item.id;
  56. }
  57. panel.attr('id', item.id);
  58. panel.addClass('menu-panel');
  59. panel.width(menuWidth);
  60. $(item.children).each(function(index, item)
  61. {
  62. var link = $('<a></a>');
  63. link.attr('class', item.styleClass);
  64. link.attr('href', item.href);
  65. link.text(item.label);
  66. var li = $('<li></li>');
  67. li.append(link);
  68. panel.append(li);
  69. });
  70. menu.append(panel);
  71. });
  72. }
  73. else
  74. {
  75. $(data).each(function(index, item)
  76. {
  77. var panel = $(item);
  78. if (panel.hasClass('menu-panel-root'))
  79. {
  80. rootPanel = '#' + panel.attr('id');
  81. }
  82. panel.width(menuWidth);
  83. menu.append(item);
  84. });
  85. }
  86. rootPanel = $(rootPanel);
  87. rootPanel.addClass('menu-panel-root');
  88. var currentPanel = rootPanel;
  89. menu.height(rootPanel.height());
  90. var wrapper = $('<div></div>').addClass('sliding-menu-wrapper').width(data.length * menuWidth);
  91. menu.wrapInner(wrapper);
  92. wrapper = $('.sliding-menu-wrapper', menu);
  93. $('a', self).on('click', function(e)
  94. {
  95. var href = $(this).attr('href'),
  96. label = $(this).text();
  97. if (wrapper.is(':animated'))
  98. {
  99. e.preventDefault();
  100. return;
  101. }
  102. if (href == '#')
  103. {
  104. e.preventDefault();
  105. }
  106. else if (href.indexOf('#menu-panel') == 0)
  107. {
  108. var target = $(href),
  109. isBack = $(this).hasClass('back'),
  110. marginLeft,
  111. marginRight;
  112. if (rtl === true){
  113. marginRight = parseInt(wrapper.css('margin-right'));
  114. }
  115. else{
  116. marginLeft = parseInt(wrapper.css('margin-left'));
  117. }
  118. // Update menu width on menu toggle
  119. var menuWidth = menu.width();
  120. // Update current panel when menu is reset
  121. if($(this).closest('ul').hasClass('menu-panel-root')){
  122. currentPanel = rootPanel;
  123. }
  124. if (isBack)
  125. {
  126. if (href == '#menu-panel-back')
  127. {
  128. target = currentPanel.prev();
  129. }
  130. if(rtl === true)
  131. properties = {marginRight: marginRight + menuWidth};
  132. else
  133. properties = {marginLeft: marginLeft + menuWidth};
  134. wrapper.stop(true, true).animate(properties, 'fast');
  135. }
  136. else
  137. {
  138. target.insertAfter(currentPanel);
  139. if (settings.backLabel === true)
  140. {
  141. $('.back', target).html('<i class="fa fa-arrow-circle-o-left back-in"></i>'+label);
  142. }
  143. else
  144. {
  145. $('.back', target).text(settings.backLabel);
  146. }
  147. if(rtl === true)
  148. properties = {marginRight: marginRight - menuWidth};
  149. else
  150. properties = {marginLeft: marginLeft - menuWidth};
  151. wrapper.stop(true, true).animate(properties,'fast');
  152. }
  153. currentPanel = target;
  154. menu.stop(true, true).animate(
  155. {
  156. height: target.height()
  157. }, 'fast');
  158. e.preventDefault();
  159. }
  160. });
  161. return this;
  162. });
  163. function process(data)
  164. {
  165. var ul = $('ul', data),
  166. panels = [];
  167. $(ul).each(function(index, item)
  168. {
  169. var panel = $(item),
  170. handler = panel.prev(),
  171. id = getNewId();
  172. if (handler.length == 1)
  173. {
  174. handler.addClass('nav-has-children dropdown-item').attr('href', '#menu-panel-' + id);
  175. handler.append('<i class="ft-arrow-right children-in"></i>')
  176. }
  177. panel.attr('id', 'menu-panel-' + id);
  178. if (index == 0)
  179. {
  180. panel.addClass('menu-panel-root');
  181. }
  182. else
  183. {
  184. panel.addClass('menu-panel');
  185. var li = $('<li></li>'),
  186. back = $('<a></a>').addClass('nav-has-parent back primary dropdown-item').attr('href', '#menu-panel-back');
  187. panel.prepend(back);
  188. }
  189. panels.push(item);
  190. });
  191. return panels;
  192. }
  193. function processJSON(data, parent)
  194. {
  195. var root = { id: 'menu-panel-' + getNewId(), children: [], root: (parent ? false : true) },
  196. panels = [];
  197. if (parent)
  198. {
  199. root.children.push(
  200. {
  201. styleClass: 'back',
  202. href: '#' + parent.id
  203. });
  204. }
  205. $(data).each(function(index, item)
  206. {
  207. root.children.push(item);
  208. if (item.children)
  209. {
  210. var panel = processJSON(item.children, root);
  211. item.href = '#' + panel[0].id;
  212. item.styleClass = 'nav';
  213. panels = panels.concat(panel);
  214. }
  215. });
  216. return [root].concat(panels);
  217. }
  218. function getNewId()
  219. {
  220. var id;
  221. do
  222. {
  223. id = Math.random().toString(36).substring(3, 8);
  224. }
  225. while (usedIds.indexOf(id) >= 0);
  226. usedIds.push(id);
  227. return id;
  228. }
  229. function updateWidth(){
  230. var wrapper = $('.sliding-menu-wrapper'),
  231. menuPanels = $('.sliding-menu-wrapper ul');
  232. if(menuPanels.length){
  233. setTimeout(function(){
  234. var menuWidth = $(selector).width();
  235. // Update wrapper width
  236. wrapper.width(menuPanels.length * menuWidth);
  237. menuPanels.each(function(index, item)
  238. {
  239. var panel = $(item);
  240. panel.width(menuWidth);
  241. });
  242. wrapper.css('margin-left','');
  243. }, 300);
  244. }
  245. }
  246. };
  247. } (jQuery));