Wednesday, October 31, 2012

Javascript FadeOut


Situation :: I have two small question mark icons on my page and when clicked, each of those icons shows related tooltip help text in a DIV and that DIV fades away in some seconds. The scenario can be better understood from the picture below.


As stated, when the 1st icon is clicked, the corresponding tooltip text is displayed and the other tooltip text is immediately hidden.











If we use fadeout() function of jQuery, we need to write the HTML and JS as shown below.

HTML 
-------
<!-- Creating the two question mark icons as displayed in the picture. -->
<span onclick = 'display_help(1); return false;'>?</span>
<span onclick = 'display_help(2); return false;'>?</span>

<!-- ToolTips, Iniatially made hidden -->
<div id='consumer_tips' style="background-color:#FFA130;width:130px;font-size:12px;color:#1658A2;display:none;padding:5px">As a Consumer, you can accept various offers from Merchants.</div>

<div id='merchant_tips' style="background-color:#FFA130;width:130px;font-size:12px;color:#1658A2;display:none;padding:5px">As a Merchant, you can offer various goodies to Consumers.</div>


JavaScript
-------------
function display_help(type)
{
  // Show FIRST TIP and FadeOUT 
  if( type == 1 )       
  { j("#merchant_tips").hide();
    j("#consumer_tips").show().fadeOut(15000);
  }

  // Show SECOND TIP and FadeOUT
  if( type == 2 )      
  { j("#consumer_tips").hide(); 
    j("#merchant_tips").show().fadeOut(15000); 
  }
}


Testing Scenario:: We have the following scenario.

1. We click on the 1st icon, 1st tooltip is shown and it starts to fade out. 2nd tooltip is made hidden.

2. We click on the 2nd icon, 1st tooltip is made hidden, the 2nd tooltip is shown and it starts to fade out.

3. We click on the 1st icon again, 2nd tooltip is hidden. 1st tooltip is shown again.

Problem ::  
If we repeat the above stated processes quickly, we'll see that the third process [stated in point 3 above] is showing first DIV in faded condition. This happens due to the timer which started the fading in first process [stated in point 1]. This timer is still in function because it has not timed-out yet as we had gone through the clicks very fast. The picture below is showing the faded effect.















Solution :: We can fix the issue by writing our own Javascript timer function. Our objective will be as follows ::

1. When 1st icon is clicked, we set a flag to 1; we start a timer for fading out; when the opacity of the tooltip DIV reaches below 0 we hide the DIV completely

2. When we click on the 2nd icon, we set another flag to 1 and clear the first flag and first timer; similarly the second DIV is made hidden when its opacity goes below 0;

3. When we again click the 1st icon, the related flag and timer are set whereas the flag and timer for second icon/toolbar are all cleared.

The code is given below .. 

<script type='text/javascript'>
function display_help( type )
{
  // Show Consumer TIPs and FadeOUT
  if( type == 1 ) 
  {   
      // Hide 2nd DIV
      j("#merchant_tips").hide();
      // Show 1st DIV
      j("#consumer_tips").show();
      // Set flag related to 1st icon
      tip1 = 1; op1 = 1.0;  
      // Clear old timer for fading 
      clearTimeout( timer1 );
      // Call the fade_out function 
      fade_out("consumer_tips", 1);  
  }
  // Show Merchant TIPS and fadeOut 
  if( type == 2 )  
  { 
     // Hide 1st DIV
     j("#consumer_tips").hide(); 
     // SHow 2nd DIV
     j("#merchant_tips").show(); 
     // Set flag related to 2nd icon/DIV
     tip2 = 1; op2 = 1.0;
     // Clear old timer for fading
     clearTimeout( timer2 );
     // Call the fade_out function
     fade_out("merchant_tips", 2);  
  }
}

// Fade_Out function, which sets timer for changing the Opacity of a DIV. 
// Lower the opacity, more faded the element looks. 

function fade_out(div_id, mode)
{
  // FOR 1st DIV/Icon  
  if(mode == 1 && tip1 == 0 ) 
  {
    clearTimeout( timer1 );
    return;
  }
  
  // FOR 1st DIV/Icon  
  // Consumer tips is fading Out
  if( mode == 1 && tip1 == 1 ) 
  {
    // Setting the timer
    timer1 = setTimeout( function(){ fade_out(div_id, mode); }, 100 );
    
    // Set the Opacity
    j("#" + div_id).css("opacity", op1);
    
    //Decrease the opacity
    op1 -= .01;
    
    // If opacity goes below 0, clear the timer
    if(op1 < 0 )
    {  
       // Clear the timer
       clearTimeout( timer1 ); 
       tip1 = 0;  
       j("#" + div_id).css("display", "none"); 
    }
  }
  
  // FOR 2nd DIV/Icon  
  if(mode == 2 && tip2 == 0 )
  {
    clearTimeout( timer2 );
    return;
  }
  
  // FOR 2nd DIV/Icon  
  // Merchant tips is fading Out
  if( mode == 2 && tip2 == 1 ) 
  {
    // Setting the timer
    timer2 = setTimeout( function(){ fade_out(div_id, mode); }, 100 );
    
    // Set the opacity
    j("#" + div_id).css("opacity", op2);
    
    // Decrease the opacity
    op2 -= .01;
    
    // If opacity goes below 0, clear the timer
    if(op2 < 0 )
    {  clearTimeout( timer2 ); 
       tip2 = 0;  
       j("#" + div_id).css("display", "none"); 
    }
  }
}    
</script>  

No comments: