Want more features on Pastebin? Sign Up, it's FREE!
Guest

jquery.mobilemenu.js

By: a guest on Apr 14th, 2013  |  syntax: JavaScript  |  size: 6.96 KB  |  views: 382  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. (function($){
  2.  
  3.        
  4.  
  5.         //plugin's default options
  6.  
  7.         var settings = {
  8.  
  9.                 combine: true,                                  //combine multiple menus into a single select
  10.  
  11.                 groupPageText: 'Main',                  //optgroup's aren't selectable, make an option for it
  12.  
  13.                 nested: true,                                   //create optgroups by default
  14.  
  15.                 prependTo: 'body',                              //insert at top of page by default
  16.  
  17.                 switchWidth: 480,                               //width at which to switch to select, and back again
  18.  
  19.                 topOptionText: 'Select a page'  //default "unselected" state
  20.  
  21.         },
  22.  
  23.        
  24.  
  25.         //used to store original matched menus
  26.  
  27.         $menus,
  28.  
  29.        
  30.  
  31.         //used as a unique index for each menu if no ID exists
  32.  
  33.         menuCount = 0,
  34.  
  35.        
  36.  
  37.         //used to store unique list items for combining lists
  38.  
  39.         uniqueLinks = [];
  40.  
  41.  
  42.  
  43.  
  44.  
  45.         //go to page
  46.  
  47.         function goTo(url){
  48.  
  49.                 document.location.href = url;
  50.  
  51.         }
  52.  
  53.        
  54.  
  55.         //does menu exist?
  56.  
  57.         function menuExists(){
  58.  
  59.                 return ($('.mnav').length) ? true : false;
  60.  
  61.         }
  62.  
  63.  
  64.  
  65.         //validate selector's matched list(s)
  66.  
  67.         function isList($this){
  68.  
  69.                 var pass = true;
  70.  
  71.                 $this.each(function(){
  72.  
  73.                         if(!$(this).is('ul') && !$(this).is('ol')){
  74.  
  75.                                 pass=false;
  76.  
  77.                         }
  78.  
  79.                 });
  80.  
  81.                 return pass;
  82.  
  83.         }//isList()
  84.  
  85.  
  86.  
  87.  
  88.  
  89.         //function to decide if mobile or not
  90.  
  91.         function isMobile(){
  92.  
  93.                 return ($(window).width() < settings.switchWidth);
  94.  
  95.         }
  96.  
  97.        
  98.  
  99.        
  100.  
  101.         //function to get text value of element, but not it's children
  102.  
  103.         function getText($item){
  104.  
  105.                 return $.trim($item.clone().children('ul, ol').remove().end().text());
  106.  
  107.         }
  108.  
  109.        
  110.  
  111.         //function to check if URL is unique
  112.  
  113.         function isUrlUnique(url){
  114.  
  115.                 return ($.inArray(url, uniqueLinks) === -1) ? true : false;
  116.  
  117.         }
  118.  
  119.        
  120.  
  121.        
  122.  
  123.         //function to do duplicate checking for combined list
  124.  
  125.         function checkForDuplicates($menu){
  126.  
  127.                
  128.  
  129.                 $menu.find(' > li').each(function(){
  130.  
  131.                
  132.  
  133.                         var $li = $(this),
  134.  
  135.                                 link = $li.find('a').attr('href'),
  136.  
  137.                                 parentLink = function(){
  138.  
  139.                                         if($li.parent().parent().is('li')){
  140.  
  141.                                                 return $li.parent().parent().find('a').attr('href');
  142.  
  143.                                         } else {
  144.  
  145.                                                 return null;
  146.  
  147.                                         }
  148.  
  149.                                 };
  150.  
  151.                                                
  152.  
  153.                         //check nested <li>s before checking current one
  154.  
  155.                         if($li.find(' ul, ol').length){
  156.  
  157.                                 checkForDuplicates($li.find('> ul, > ol'));
  158.  
  159.                         }
  160.  
  161.                
  162.  
  163.                         //remove empty UL's if any are left by LI removals
  164.  
  165.                         if(!$li.find(' > ul li, > ol li').length){
  166.  
  167.                                 $li.find('ul, ol').remove();
  168.  
  169.                         }
  170.  
  171.                
  172.  
  173.                         //if parent <li> has a link, and it's not unique, append current <li> to the "unique parent" detected earlier
  174.  
  175.                         if(!isUrlUnique(parentLink(), uniqueLinks) && isUrlUnique(link, uniqueLinks)){
  176.  
  177.                                 $li.appendTo(
  178.  
  179.                                         $menu.closest('ul#mmnav').find('li:has(a[href='+parentLink()+']):first ul')
  180.  
  181.                                 );
  182.  
  183.                         }
  184.  
  185.                        
  186.  
  187.                         //otherwise, check if the current <li> is unique, if it is, add it to the unique list
  188.  
  189.                         else if(isUrlUnique(link)){
  190.  
  191.                                 uniqueLinks.push(link);
  192.  
  193.                         }
  194.  
  195.                        
  196.  
  197.                         //if it isn't, remove it. Simples.
  198.  
  199.                         else{
  200.  
  201.                                 $li.remove();
  202.  
  203.                         }
  204.  
  205.                
  206.  
  207.                 });
  208.  
  209.         }
  210.  
  211.        
  212.  
  213.        
  214.  
  215.         //function to combine lists into one
  216.  
  217.         function combineLists(){
  218.  
  219.                
  220.  
  221.                 //create a new list
  222.  
  223.                 var $menu = $('<ul id="mmnav" />');
  224.  
  225.                
  226.  
  227.                 //loop through each menu and extract the list's child items
  228.  
  229.                 //then append them to the new list
  230.  
  231.                 $menus.each(function(){
  232.  
  233.                         $(this).children().clone().appendTo($menu);
  234.  
  235.                 });
  236.  
  237.                
  238.  
  239.                 //de-duplicate any repeated items
  240.  
  241.                 checkForDuplicates($menu);
  242.  
  243.                                
  244.  
  245.                 //return new combined list
  246.  
  247.                 return $menu;
  248.  
  249.                
  250.  
  251.         }//combineLists()
  252.  
  253.        
  254.  
  255.        
  256.  
  257.        
  258.  
  259.         //function to create options in the select menu
  260.  
  261.         function createOption($item, $container, text){
  262.  
  263.                
  264.  
  265.                 //if no text param is passed, use list item's text, otherwise use settings.groupPageText
  266.  
  267.                 if(!text){
  268.  
  269.                         $('<option value="'+$item.find('a:first').attr('href')+'">'+$.trim(getText($item))+'</option>').appendTo($container);
  270.  
  271.                 } else {
  272.  
  273.                         $('<option value="'+$item.find('a:first').attr('href')+'">'+text+'</option>').appendTo($container);
  274.  
  275.                 }
  276.  
  277.        
  278.  
  279.         }//createOption()
  280.  
  281.        
  282.  
  283.        
  284.  
  285.        
  286.  
  287.         //function to create option groups
  288.  
  289.         function createOptionGroup($group, $container){
  290.  
  291.                
  292.  
  293.                 //create <optgroup> for sub-nav items
  294.  
  295.                 var $optgroup = $('<optgroup label="'+$.trim(getText($group))+'" />');
  296.  
  297.                
  298.  
  299.                 //append top option to it (current list item's text)
  300.  
  301.                 createOption($group,$optgroup, settings.groupPageText);
  302.  
  303.        
  304.  
  305.                 //loop through each sub-nav list
  306.  
  307.                 $group.children('ul, ol').each(function(){
  308.  
  309.                
  310.  
  311.                         //loop through each list item and create an <option> for it
  312.  
  313.                         $(this).children('li').each(function(){
  314.  
  315.                                 createOption($(this), $optgroup);
  316.  
  317.                         });
  318.  
  319.                 });
  320.  
  321.                
  322.  
  323.                 //append to select element
  324.  
  325.                 $optgroup.appendTo($container);
  326.  
  327.                
  328.  
  329.         }//createOptionGroup()
  330.  
  331.  
  332.  
  333.        
  334.  
  335.        
  336.  
  337.         //function to create <select> menu
  338.  
  339.         function createSelect($menu){
  340.  
  341.        
  342.  
  343.                 //create <select> to insert into the page
  344.  
  345.                 var $select = $('<select id="mm'+menuCount+'" class="mnav" />');
  346.  
  347.                 menuCount++;
  348.  
  349.                
  350.  
  351.                 //create default option if the text is set (set to null for no option)
  352.  
  353.                 if(settings.topOptionText){
  354.  
  355.                         createOption($('<li>'+settings.topOptionText+'</li>'), $select);
  356.  
  357.                 }
  358.  
  359.                
  360.  
  361.                 //loop through first list items
  362.  
  363.                 $menu.children('li').each(function(){
  364.  
  365.                
  366.  
  367.                         var $li = $(this);
  368.  
  369.  
  370.  
  371.                         //if nested select is wanted, and has sub-nav, add optgroup element with child options
  372.  
  373.                         if($li.children('ul, ol').length && settings.nested){
  374.  
  375.                                 createOptionGroup($li, $select);
  376.  
  377.                         }
  378.  
  379.                        
  380.  
  381.                         //otherwise it's a single level select menu, so build option
  382.  
  383.                         else {
  384.  
  385.                                 createOption($li, $select);                    
  386.  
  387.                         }
  388.  
  389.                                                
  390.  
  391.                 });
  392.  
  393.                
  394.  
  395.                 //add change event and prepend menu to set element
  396.  
  397.                 $select
  398.  
  399.                         .change(function(){goTo($(this).val());})
  400.  
  401.                         .prependTo(settings.prependTo);
  402.  
  403.        
  404.  
  405.         }//createSelect()
  406.  
  407.  
  408.  
  409.        
  410.  
  411.         //function to run plugin functionality
  412.  
  413.         function runPlugin(){
  414.  
  415.        
  416.  
  417.                 //menu doesn't exist
  418.  
  419.                 if(isMobile() && !menuExists()){
  420.  
  421.                        
  422.  
  423.                         //if user wants to combine menus, create a single <select>
  424.  
  425.                         if(settings.combine){
  426.  
  427.                                 var $menu = combineLists();
  428.  
  429.                                 createSelect($menu);
  430.  
  431.                         }
  432.  
  433.                        
  434.  
  435.                         //otherwise, create a select for each matched list
  436.  
  437.                         else{
  438.  
  439.                                 $menus.each(function(){
  440.  
  441.                                         createSelect($(this));
  442.  
  443.                                 });
  444.  
  445.                         }
  446.  
  447.                 }
  448.  
  449.                
  450.  
  451.                 //menu exists, and browser is mobile width
  452.  
  453.                 if(isMobile() && menuExists()){
  454.  
  455.                         $('.mnav').show();
  456.  
  457.                         $menus.hide();
  458.  
  459.                 }
  460.  
  461.                        
  462.  
  463.                 //otherwise, hide the mobile menu
  464.  
  465.                 if(!isMobile() && menuExists()){
  466.  
  467.                         $('.mnav').hide();
  468.  
  469.                         $menus.show();
  470.  
  471.                 }
  472.  
  473.                
  474.  
  475.         }//runPlugin()
  476.  
  477.  
  478.  
  479.        
  480.  
  481.        
  482.  
  483.         //plugin definition
  484.  
  485.         $.fn.mobileMenu = function(options){
  486.  
  487.  
  488.  
  489.                 //override the default settings if user provides some
  490.  
  491.                 if(options){$.extend(settings, options);}
  492.  
  493.                
  494.  
  495.                 //check if user has run the plugin against list element(s)
  496.  
  497.                 if(isList($(this))){
  498.  
  499.                         $menus = $(this);
  500.  
  501.                         runPlugin();
  502.  
  503.                         $(window).resize(function(){runPlugin();});
  504.  
  505.                 } else {
  506.  
  507.                         alert('mobileMenu only works with <ul>/<ol>');
  508.  
  509.                 }
  510.  
  511.                                
  512.  
  513.         };//mobileMenu()
  514.  
  515.        
  516.  
  517. })(jQuery);
clone this paste RAW Paste Data