views:

4459

answers:

6

Hello guys,

I have two divs (one of them hidden with CSS), which I'm fading in and out in alternance inside a common space, on hover.

This is the markup :

<div id="wrap">

    <div class="image">
     <img src="http://domain.com/images/image.png"&gt;
    </div>

    <div class="text hide">
     <p>Text text text</p>
    </div>

</div>

And I was applying this jQuery code to fade out the image - and fading in the text, on hover :

<script type="text/javascript">
$(function(){
$('#wrap').hover(
     function(){
      $('#wrap .image').fadeOut(100, function(){
       $('#wrap .text').fadeIn(100);       
      });
     },
     function(){
      $('#wrap .text').fadeOut(100, function(){
       $('#wrap .image').fadeIn(100);       
      });
     }
     );
});
</script>

But the problem is that the text div gets sticky and won't fade out - always that the mouse movement is too quick.

Do you know where can it be the solution to this ?

I set up an online test : http://paragraphe.org/stickytext/test.html

Thanks for any tip

A: 

Your code never fades out the text div. Both functions of the hover event will fade out the image and fade in the text.

Philippe Leybaert
true ! sorry about that, I copy-pasted the code here too fast. Going to edit that.
Peanuts
A: 

You have the same code in both hover functions. Shouldn't you replace the selectors in second case?

<script type="text/javascript">
$(function(){
$('#wrap').hover(
    function(){
            $('#wrap .image').fadeOut(100, function(){
                $('#wrap.text').fadeIn(100);
            });
    },
    function(){
            $('#wrap.text').fadeOut(100, function(){
               $('#wrap.image').fadeIn(100);                                            
            });
    }
    );
});
</script>
RaYell
Yep, sorry guys I didn't set correctly here the selectors. Going to edit it properly.
Peanuts
+1  A: 

try using .stop() on your hover-out function, which will prevent the race-condition where you rapidly move your mouse over the divs

<script type="text/javascript">
$(function(){
$('#wrap').hover(
    function(){
            $('#wrap .image').fadeOut(100, function(){
                $('#wrap.text').fadeIn(100);
            });
    },
    function(){
            $('#wrap.text').stop().fadeOut(100, function(){
               $('#wrap.image').stop().fadeIn(100);                                            
            });
    }
    );
});
</script>
duckyflip
duckyflip - thanks ! This seems to prevent the sticky div. However the images find it now difficult to come back again (sometimes they get in the middle of the fading in)
Peanuts
+1  A: 

If your wrapper doesn't have a width AND height on it you may get some strange results as it shrinks once the image element is removed. To see, add a border and fixed height / width around the wrapper. Or at least use the same height for the image and text divs.

<style type="text/css">
#wrap { width: 200px; height: 200px; border: 1px solid black; }
</style>

EDITED

Removed a code example that wasn't applicable to what you're trying to accomplish.

ScottE
ScottE - nice one, the bug was indeed in the CSS, I had a position:relative for the text, which I changed to a negative top margin, plus a float:left. I will set up the width and height too, just to assure it.
Peanuts
+1  A: 

Try using the queue:

<script type="text/javascript">
$(function(){
    $('#wrap').hover(
        function(){
            $('#wrap .image').stop(true).fadeOut(100);
            $('#wrap .image').queue(function(){
                $('#wrap.text').fadeIn(100);
                $(this).dequeue();
            });
        },
        function(){
            $('#wrap .image').stop(true).queue(function(){
                $('#wrap.text').fadeOut(100);
                $(this).dequeue();
            });
            $('#wrap .image').fadeIn(100);
        }
    );
});
</script>

The jQuery queue is per element, so what I'm trying to do here is to launch the text effects under de image queue.

And let me give you another suggestion. If your intention is to apply this effect to various images use class instead of id.

...
    $('.wrap').hover(
        function(){
            var wrap = this;
            $('.image', wrap).stop(true).fadeOut(100);
            $('.image', wrap).queue(function(){
                $('.text', wrap).fadeIn(100);
                $(this).dequeue();
            });
....

This way you only need to call this once.

Serhii
Serhii - thanks for that one.
Peanuts
A: 

Hi guys, thanks for all the tips :

I tried to use the mouseenter / mouseleave events, since they seem to look in detail for the divs they are dealing with (as seen here), but nothing changed. So seeing that all the usual jQuery instructions weren't responding I've checked out as suggested my CSS.

And there was the trick.

What I had :

.text p{position:relative; top:-370px; padding: 0 10px}

was setting up a huge, empty space that the browser was interpreting as "not left still" by the cursor (I noticed that overflying that empty space was making the text to respond properly).

So I changed to that :

.text {margin-top:-370px; padding: 0 10px; float:left}

Which lets the "p" tag alone, and positions the second block up in the div, but without a trace of empty space behind it.

Then, concerning the snippet, it will work as well with mouseenter / moseleave and hover :

<script type="text/javascript">
$(function(){
$('#wrap').mouseenter(
     function(){
      $('#wrap .image').fadeOut(100, function(){
       $('#wrap .text').fadeIn(100);       
      });
     }
     );
$('#wrap').mouseleave(
     function(){
      $('#wrap .text').fadeOut(100, function(){
       $('#wrap .image').fadeIn(100);       
      });
     }
     );
});
</script>

This is the improved version http://paragraphe.org/nice/test.html

Peanuts