views:

31

answers:

1

My question is similar, but different from jquery-hover-menu-when-hovering-over-child-menu-disappears.

I originally had the hover event on the li.item, which was a little quirky, but did what i needed it to do. I switched the hover to the span so that the event would fire on the text block, rather than the list block, which expands the full width of the list.

The effect I'm trying to achieve is when hovering over ul.sub. I'd like it to continue with the animation in queue from span.text's hover, which is displaying it, but also keep it open.

What is happening is that the mouse is leaving the span, so the li.item is firing its mouseout portion of the trigger.


jsFiddle Page


HTML


   <ul id="main">
       <li class="head">Title Bar</li>
       <li class="item odd">
           <span class="text">A</span>
           <ul class="sub">
               <li>1</li>
               <li>2</li>
           </ul>
       </li>
       <li class="item even">
           <span class="text">B</span>
           <ul class="sub">
               <li>3</li>
               <li>4</li>
           </ul>
       </li>
       <li class="item odd">
           <span class="text">C</span>
           <ul class="sub">
               <li>5</li>
               <li>6</li>
           </ul>
       </li>
       <li class="item even">
           <span class="text">D</span>
           <ul class="sub">
               <li>7</li>
               <li>8</li>
           </ul>
       </li>
   </ul>


CSS


/* colors used are not for production; they are
   used only to enhance the example's visual distinction */

   #main{width:10em;}
   .head,.item{border:1px solid black;padding:.5em;}
   .head{font-weight:bold; background:#336; color:#fff; cursor:pointer;}
   .item{background:#f90;}
   .sub{display:none;}
   .sub li{padding-left:1em;}
   .text,.sub{cursor:pointer;}


JavaScript


   $(document).ready(function(){
      // specific here because of other divs/list items

      $('#main li.item span.text').hover(function(){
         $(this).siblings().stop(true,true).toggle('slow');     
      });       

      $('li.head').hover(function(){
         $(this).parent().find('ul.sub').stop(true,true).toggle('slow');
      });
   });

Edit:

I think something along these lines is what I need, however the animation is refired when going from the sub to the span.

$(document).ready(function(){
   // specific here because of other divs/list items

   $('#main li.item span.text').hover(
       function(){$(this).siblings().stop(false,true).show('slow');}
      ,function(){$(this).siblings().stop(true,true).hide('slow');}     
   );    

   $('#main li.item ul.sub').hover(
        function(){$(this).stop(false,true).show();}
       ,function(){$(this).stop(false,true).hide('slow');}
   );    

   $('li.head').hover(function(){
      $(this).parent().find('ul.sub').stop(true,true).toggle('slow');
   });
});
+1  A: 

Split the hover behavior into its two constituents, mouseenter and mouseleave. Also split toggle() into show() and hide(). Bind mouseenter to the span.text and mouseleave to the li.item:

$(document).ready(function() {
    // specific here because of other divs/list items
    $('#main li.item span.text').mouseenter(function() {
        $(this).siblings().stop(true, true).show('slow');
    });

    $('#main li.item').mouseleave(function() {
        $(this).children("ul").stop(true, true).hide('slow');
    });

    $('li.head').hover(function() {
        $(this).parent().find('ul.sub').stop(true, true).toggle('slow');
    });
});

That way, the hover is not triggered by whitespace, which is what you want.

Frédéric Hamidi
I just posted something like that: see the edit; however I think yours is the solution that would make everything more fluid when going from the span-to-sub and back.
vol7ron
Well, you're still calling `hover()`, so you can't split the `mouseenter` and `mouseleave` behaviors and bind them to two different elements, which is key to my answer.
Frédéric Hamidi
@Frederic - yep :) exactly, just stating I was headed to the same place but you got there before me. I'll test it first then come back and plus/check you out =]
vol7ron
Good, now you're doing it, but I should point out my answer doesn't exhibit your problem: the animation is not refired when going from the sub to the span :)
Frédéric Hamidi
Do you have a copy of the jsFiddle that works, everything looks valid, but for some reason it isn't triggering the show. **Edit:** nevermind, spelling error two 'e' in 'mouseenter'
vol7ron
It's not the exact solution, but it's probably the most efficient. I think the exact would be setting a timer on the `sub`'s leave and using a variable to track if the mouse entered on the span (setting it to false on mouseenter of sub). -- I think that might be what they're doing in the link to the other similar question; I just hadn't got to thinking about why they were using a timer, which is to get around the leave event from being fired.
vol7ron