Adamor
Adamor

Reputation: 23

Jquery fade-in and out loop

I've updated an old javascript of mine to work with Jquery recently.

It does the following:

When a user hovers over a link with a class of content-fade it causes content with an associated id to fade-in and then within a set time fade-out unless the user leaves their mouse on the content.

I need to change the script again and have it loop through a set of ids aka id1, id2, id3...etc. Ideally causing the only the content with the individual associated id to show. I've just started working with JQuery and I'm not sure how best to approach this. The code is below if anyone could point me in the right direction I would appreciate it.

  $(document).ready(function() {
        var hide = false;
        $(".content-fade").hover(function(){
            if (hide) clearTimeout(hide);
            $("#id").fadeIn();
        }, function() {
            hide = setTimeout(function() {$("#id").fadeOut("slow");}, 250);
        });
        $("#id").hover(function(){
            if (hide) clearTimeout(hide);
       }, function() {
            hide = setTimeout(function() {$("#id").fadeOut("slow");}, 250);
        });
 });

Upvotes: 2

Views: 888

Answers (4)

Rob Cowie
Rob Cowie

Reputation: 22619

If I understand your requirements correctly, you are on the right track.

  • Define target elements by storing a jQuery selector in a data attribute (data-hover-target)
  • On mouseenter (hover), fade the target element in.
  • On mouseleave fade the target out with a delay
  • Clear the animation queue for the target element on mouseenter to prevent the fadeOut if it is pending. Thus, if the user moves the cursor away from the link, then immediately back again - before the delayed fadeOut has started - the fadeOut will be cancelled and the target element will remain visible.

See below for the code and http://jsbin.com/uruzaw/11/ for a working example.

$(function(){

  $('.content-fade').hover(
    // fadeIn on mouse
    function(event){
      var $this = $(this);
      var $target = $($this.data('hoverTarget'));
      $target.clearQueue().fadeIn(500);
    }, 

    // fadeOut on mouseout
    function(event){
      var $this = $(this);
      var $target = $($this.data('hoverTarget'));
      $target.delay(500).fadeOut(500);
    }
  );

});

EDIT I think I misunderstood your requirements. If you wish to prevent fadeOut of the content when on hover of both the link and the content itself, the following should suffice. It's basically what you have written but using jQuery animation queue with .delay() in place of setTimeout(). See http://jsbin.com/uruzaw/13/

$(function(){

  var HOVER_DELAY = 1000;

  $('.content-fade').each(function(){
    var $this = $(this);
    var $target = $($this.data('hoverTarget'));

    var fadeTargetElem = function(){
      $target.delay(HOVER_DELAY).fadeOut(500);
    };

    // bind to mouseenter
    $this
      .mouseenter(function(event){
        $target.clearQueue().fadeIn(500);
      })
      // bind to mouseleave
      .mouseleave(function(event){
        fadeTargetElem();
      });

    // bind to mouseenter of target
    $target
      .mouseenter(function(event){
        $target.clearQueue();
      })
      // bind to mouseleave of target
      .mouseleave(function(event){
        fadeTargetElem();
      });
    });
});

Upvotes: 1

Tim Joyce
Tim Joyce

Reputation: 4517

You can attach data to each class so that when you hover over it you know what id is supposed to be shown

<div class="content-fade" data-for="#1">hover for #1</div>
<div class="content-fade" data-for="#2">hover for #2</div>
<div class="content-fade" data-for="#3">hover for #3</div>

$(function(){
    $('.content-fade').bind('hover', function(){
        var idToShow = $(this).data('for');
        $(idToShow).fadeIn('slow').delay(1500).fadeOut('slow');
    });
});

Upvotes: 0

Yes Barry
Yes Barry

Reputation: 9876

A simple for loop would do the trick, if your ids are numbered that is. The question, how are your "ids" associated with their .content-fade counterparts in the first place? The answer to that question will lead you to the solution.

If each .content-fade link has an id attr set also, then you could parse that and use it when attaching the mouseenter/mouseleave events.

Say:

<a class="content-fade" id="link-1">Link 1</a>
<a class="content-fade" id="link-2">Link 1</a>

Then you could parse it like this:

var hide = false, id;
$(".content-fade").hover(function() {
    if (hide) clearTimeout(hide);
    id = this.id.split('-')[1];
    $("#id-" + id).fadeIn();
}, function() {
    id = this.id.split('-')[1];
    hide = setTimeout(function() {$("#id-" + id).fadeOut("slow");}, 250);
});

This, of course, means having to manage all of your different timeouts.

Upvotes: 0

defau1t
defau1t

Reputation: 10619

To iterate through all of these ids, you need to add a class to all of these elements and take the action at each iteration by using each

Upvotes: 0

Related Questions