Advertisement
Guest User

jquery.mobilemenu.js

a guest
Apr 14th, 2013
656
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement