0

Some of my main menu items have dropdown menus, some not. I would like to set which ones show up on hover and on click, and which ones do not. In the example below, I would like to forbid first and fourth dropdowns to show up, because they have only one item.

<div id="main-menu">
  <ul>
    <li><a href="http://piirissaareturism.ee/avasta-piirissaar/">Avasta Piirissaar</a>
      <ul class="dropdown-menu">
        <li><a rel="bookmark" href="http://piirissaareturism.ee/avasta-piirissaar/welcome-to-your-site">Welcome to Your Site!</a></li>
       </ul>
     </li>
     <li><a href="http://piirissaareturism.ee/kasulik-info/">Kasulik info</a>
       <ul class="dropdown-menu">
         <li><a rel="bookmark" href="http://piirissaareturism.ee/kasulik-info/toitlustus">Toitlustus</a></li>
         <li><a rel="bookmark" href="http://piirissaareturism.ee/kasulik-info/majutus">Majutus</a></li>
       </ul>
     </li>
     <li><a href="http://piirissaareturism.ee/puhkajale/">Puhkajale</a></li>
     <li><a href="http://piirissaareturism.ee/meist/">Meist</a>
       <ul class="dropdown-menu">
         <li><a rel="bookmark" href="http://piirissaareturism.ee/meist/mtu-piirissaare-turism">MTÜ Piirissaare Turism</a></li>
       </ul>
     </li>
   </ul>
 </div>

I use also jquery to do the following:

first: slide down dropdown on hover

$('#main-menu ul li').hover(
  function () {
    $('ul', this).stop(true, true).delay(100).slideDown(300);
  },
  function () {
    $('ul', this).stop(true, true).slideUp(300);            
  });

second: if menu item has dropdown - show it on click and do not go to item's url, otherwise go to that item's url.

$('#main-menu ul li:has(.dropdown-menu)').on('click', function (event) {
  if ($(event.target).parents('ul.dropdown-menu').length > 0) {
    event.stopPropagation();
  } else {
    event.preventDefault();
  }
  $(this).find('ul').slideToggle();
});

I know, my description is abstruse, but look at my jsfiddle to understand better.

ghost_dad
  • 1,308
  • 2
  • 12
  • 21
Gallex
  • 311
  • 3
  • 8
  • 18
  • For user experience should the interaction with your dropdown menus not be consistent? Why would you want to have 'onClick' on some and 'hover' on the others? – midda25 Jun 18 '16 at 16:59
  • Yes, that's what i intend to do – Gallex Jun 19 '16 at 10:08

2 Answers2

1

You can use :nth-child() to filter out elements not required,

Fiddle

$('#main-menu ul li:not(:nth-child(1),:nth-child(4))').hover(
    ...

For :first,:last to work, I had to modify the selector to get only direct descendents.

$('#main-menu > ul > li:not(:first,:last)').hover(

Fiddle


$('#main-menu > ul > li:not(:first,:last)').hover(
  function() {
    $('ul', this).stop(true, true).delay(100).slideDown(300);
  },
  function() {
    $('ul', this).stop(true, true).slideUp(300);
  });

$('#main-menu > ul > li:not(:first,:last):has(.dropdown-menu)').on('click', function(event) {
  if ($(event.target).parents('ul.dropdown-menu').length > 0) {
    event.stopPropagation();
  } else {
    event.preventDefault();
  }
  $(this).find('ul').slideToggle();
});
Shaunak D
  • 20,588
  • 10
  • 46
  • 79
0

See https://stackoverflow.com/a/12198561/3671484 for a great answer on this. It allows you to check for a specific number of children inside a parent

For example it to check for children elements inside a parent:

/* two items */
  li:first-child:nth-last-child(2),
  li:first-child:nth-last-child(2) ~ li {
  width: 50%;
}

This checks that the first-child (li:first-child) is two sibling elements before the last-child (:nth-last-child(2)) and also will set the width of this item to 50% along with all of its siblings (~ li)

Community
  • 1
  • 1
midda25
  • 152
  • 1
  • 2
  • 12